From 1d3090326210c6e6f7ec5432799ded25b75bba46 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 28 May 2009 11:23:00 +0200 Subject: beta 2009.05.28 11:23 --- tex/context/base/attr-ini.lua | 853 +- tex/context/base/attr-ini.tex | 163 +- tex/context/base/back-ini.lua | 75 + tex/context/base/back-ini.tex | 896 +++ tex/context/base/back-pdf.lua | 189 + tex/context/base/back-pdf.tex | 3226 ++++++++ tex/context/base/bibl-bib.lua | 233 + tex/context/base/bibl-bib.tex | 29 + tex/context/base/bibl-tst.lua | 21 + tex/context/base/catc-act.tex | 61 + tex/context/base/catc-ctx.tex | 207 + tex/context/base/catc-def.tex | 142 + tex/context/base/catc-ini.lua | 28 + tex/context/base/catc-ini.mkii | 229 + tex/context/base/catc-ini.mkiv | 255 + tex/context/base/catc-sym.tex | 118 + tex/context/base/char-cmp.lua | 2 + tex/context/base/char-def.lua | 1248 ++- tex/context/base/char-enc.lua | 163 + tex/context/base/char-enc.tex | 18 + tex/context/base/char-ini.lua | 619 +- tex/context/base/char-ini.tex | 40 +- tex/context/base/char-map.lua | 19 +- tex/context/base/char-syn.lua | 140 - tex/context/base/char-utf.lua | 146 +- tex/context/base/char-utf.tex | 26 +- tex/context/base/chem-ini.lua | 74 + tex/context/base/chem-ini.mkiv | 42 + tex/context/base/chem-str-test.tex | 560 ++ tex/context/base/chem-str.lua | 488 ++ tex/context/base/chem-str.mkiv | 526 ++ tex/context/base/colo-ext.mkii | 57 + tex/context/base/colo-ext.mkiv | 57 + tex/context/base/colo-ext.tex | 57 - tex/context/base/colo-hex.mkii | 115 + tex/context/base/colo-hex.mkiv | 115 + tex/context/base/colo-hex.tex | 120 +- tex/context/base/colo-ini.lua | 181 +- tex/context/base/colo-ini.mkii | 922 ++- tex/context/base/colo-ini.mkiv | 983 ++- tex/context/base/colo-ini.tex | 1051 --- tex/context/base/colo-run.tex | 3 +- tex/context/base/cont-cs.tex | 10 +- tex/context/base/cont-de.tex | 10 +- tex/context/base/cont-en.tex | 8 +- tex/context/base/cont-fil.tex | 2 +- tex/context/base/cont-fr.tex | 10 +- tex/context/base/cont-gb.tex | 10 +- tex/context/base/cont-it.tex | 10 +- tex/context/base/cont-log.tex | 71 +- tex/context/base/cont-new.mkiv | 88 +- tex/context/base/cont-new.tex | 100 +- tex/context/base/cont-nl.tex | 10 +- tex/context/base/cont-old.tex | 2 +- tex/context/base/cont-pe.tex | 10 +- tex/context/base/cont-ro.tex | 10 +- tex/context/base/cont-sys.ori | 9 +- tex/context/base/cont-usr.ori | 2 +- tex/context/base/context-base.lmx | 38 + tex/context/base/context-characters.lmx | 66 +- tex/context/base/context-debug.lmx | 66 +- tex/context/base/context-error.lmx | 46 +- tex/context/base/context-fonttest.lmx | 47 + tex/context/base/context-help.lmx | 88 + tex/context/base/context-timing.lmx | 52 + tex/context/base/context.css | 15 + tex/context/base/context.mkii | 198 +- tex/context/base/context.mkiv | 422 +- tex/context/base/context.rme | 85 + tex/context/base/context.tex | 15 +- tex/context/base/core-bar.tex | 2 +- tex/context/base/core-blk.lua | 145 - tex/context/base/core-blk.mkiv | 109 - tex/context/base/core-blk.tex | 130 +- tex/context/base/core-box.tex | 3 +- tex/context/base/core-buf.lua | 194 +- tex/context/base/core-buf.mkii | 326 +- tex/context/base/core-buf.mkiv | 308 +- tex/context/base/core-buf.tex | 250 - tex/context/base/core-con.lua | 281 +- tex/context/base/core-con.mkii | 775 +- tex/context/base/core-con.mkiv | 831 +- tex/context/base/core-con.tex | 744 -- tex/context/base/core-ctx.lua | 41 +- tex/context/base/core-ctx.mkii | 2 +- tex/context/base/core-ctx.mkiv | 3 +- tex/context/base/core-ctx.tex | 22 - tex/context/base/core-dat.tex | 66 +- tex/context/base/core-def.mkii | 77 + tex/context/base/core-def.mkiv | 74 + tex/context/base/core-def.tex | 27 - tex/context/base/core-des.tex | 7 +- tex/context/base/core-env.mkii | 543 ++ tex/context/base/core-env.mkiv | 472 ++ tex/context/base/core-fig.tex | 4 +- tex/context/base/core-fil.tex | 56 +- tex/context/base/core-fld.mkii | 1080 +++ tex/context/base/core-fld.mkiv | 1079 +++ tex/context/base/core-fld.tex | 1080 --- tex/context/base/core-fnt.mkii | 726 ++ tex/context/base/core-fnt.mkiv | 498 ++ tex/context/base/core-fnt.tex | 726 -- tex/context/base/core-gen.tex | 137 +- tex/context/base/core-grd.tex | 2 +- tex/context/base/core-inc.lua | 608 +- tex/context/base/core-inc.mkii | 95 +- tex/context/base/core-inc.mkiv | 12 +- tex/context/base/core-inc.tex | 18 - tex/context/base/core-ini.tex | 2 +- tex/context/base/core-ins.tex | 42 +- tex/context/base/core-int.mkii | 2217 ++++++ tex/context/base/core-int.mkiv | 2036 +++++ tex/context/base/core-int.tex | 2355 ------ tex/context/base/core-itm.tex | 36 +- tex/context/base/core-job.lua | 154 +- tex/context/base/core-job.mkii | 316 +- tex/context/base/core-job.mkiv | 333 +- tex/context/base/core-job.tex | 368 - tex/context/base/core-lme.tex | 2 +- tex/context/base/core-lnt.tex | 2 +- tex/context/base/core-lst.tex | 3 +- tex/context/base/core-ltb.tex | 856 -- tex/context/base/core-mak.tex | 2 +- tex/context/base/core-mar.tex | 5 +- tex/context/base/core-mat.tex | 60 +- tex/context/base/core-mis.mkii | 2676 +++++++ tex/context/base/core-mis.mkiv | 2606 ++++++ tex/context/base/core-mis.tex | 2733 ------- tex/context/base/core-nav.mkii | 379 + tex/context/base/core-nav.mkiv | 425 + tex/context/base/core-nav.tex | 379 - tex/context/base/core-new.tex | 304 - tex/context/base/core-not.tex | 8 +- tex/context/base/core-ntb.tex | 1573 ---- tex/context/base/core-num.tex | 2 +- tex/context/base/core-obj.lua | 7 +- tex/context/base/core-obj.mkii | 309 +- tex/context/base/core-obj.mkiv | 220 +- tex/context/base/core-obj.tex | 365 - tex/context/base/core-par.tex | 2 +- tex/context/base/core-pgr.tex | 12 +- tex/context/base/core-pos.lua | 4 +- tex/context/base/core-pos.mkii | 759 +- tex/context/base/core-pos.mkiv | 789 +- tex/context/base/core-pos.tex | 767 -- tex/context/base/core-ref.lua | 106 - tex/context/base/core-ref.mkii | 90 - tex/context/base/core-ref.mkiv | 107 - tex/context/base/core-ref.tex | 261 +- tex/context/base/core-reg.lua | 186 - tex/context/base/core-reg.mkii | 33 - tex/context/base/core-reg.mkiv | 40 - tex/context/base/core-reg.tex | 55 +- tex/context/base/core-rul.lua | 1 - tex/context/base/core-rul.mkii | 3562 +++++++++ tex/context/base/core-rul.mkiv | 3635 ++++++++- tex/context/base/core-rul.tex | 3590 --------- tex/context/base/core-sec.mkii | 2620 ------ tex/context/base/core-sec.mkiv | 2621 ------ tex/context/base/core-sec.tex | 2572 ++++++ tex/context/base/core-snc.tex | 4 +- tex/context/base/core-spa.lua | 1979 ++--- tex/context/base/core-spa.mkii | 4648 ++++++++++- tex/context/base/core-spa.mkiv | 4176 +++++++++- tex/context/base/core-spa.tex | 4637 ----------- tex/context/base/core-stg.tex | 4 +- tex/context/base/core-syn.lua | 127 - tex/context/base/core-syn.mkii | 28 - tex/context/base/core-syn.mkiv | 34 - tex/context/base/core-syn.tex | 42 +- tex/context/base/core-sys.mkii | 384 +- tex/context/base/core-sys.mkiv | 373 +- tex/context/base/core-sys.tex | 401 - tex/context/base/core-tab.tex | 2499 ------ tex/context/base/core-tbl.tex | 1436 ---- tex/context/base/core-trf.tex | 28 +- tex/context/base/core-tsp.tex | 427 - tex/context/base/core-two.lua | 20 +- tex/context/base/core-two.mkii | 65 +- tex/context/base/core-two.mkiv | 77 +- tex/context/base/core-two.tex | 103 - tex/context/base/core-uti.lua | 253 +- tex/context/base/core-uti.mkii | 305 +- tex/context/base/core-uti.mkiv | 95 +- tex/context/base/core-uti.tex | 382 - tex/context/base/core-var.tex | 568 +- tex/context/base/core-ver.mkii | 1124 ++- tex/context/base/core-ver.mkiv | 1084 ++- tex/context/base/core-ver.tex | 1120 --- tex/context/base/core-vis.tex | 32 +- tex/context/base/data-aux.lua | 57 + tex/context/base/data-bin.lua | 26 + tex/context/base/data-con.lua | 122 + tex/context/base/data-crl.lua | 58 + tex/context/base/data-ctx.lua | 29 + tex/context/base/data-gen.lua | 9 + tex/context/base/data-inp.lua | 15 + tex/context/base/data-kps.lua | 101 + tex/context/base/data-lst.lua | 58 + tex/context/base/data-lua.lua | 55 + tex/context/base/data-out.lua | 10 + tex/context/base/data-pre.lua | 90 + tex/context/base/data-res.lua | 2029 +++++ tex/context/base/data-tex.lua | 220 + tex/context/base/data-tmf.lua | 72 + tex/context/base/data-tmp.lua | 174 + tex/context/base/data-tre.lua | 43 + tex/context/base/data-use.lua | 127 + tex/context/base/data-zip.lua | 241 + tex/context/base/enco-cyr.tex | 2 + tex/context/base/enco-def.tex | 6 +- tex/context/base/enco-fpl.tex | 2 +- tex/context/base/enco-ini.mkii | 1125 ++- tex/context/base/enco-ini.mkiv | 583 +- tex/context/base/enco-ini.tex | 1228 --- tex/context/base/enco-mis.tex | 37 - tex/context/base/enco-pfr.mkii | 20 - tex/context/base/enco-pfr.mkiv | 22 - tex/context/base/enco-pfr.tex | 18 +- tex/context/base/enco-run.tex | 52 +- tex/context/base/enco-t5.tex | 4 +- tex/context/base/enco-utf.tex | 3126 -------- tex/context/base/enco-x5.tex | 34 +- tex/context/base/filt-ini.tex | 62 +- tex/context/base/font-afm.lua | 344 +- tex/context/base/font-bfm.tex | 2 +- tex/context/base/font-chi.tex | 2 +- tex/context/base/font-chk.lua | 80 + tex/context/base/font-cid.lua | 143 + tex/context/base/font-col.lua | 98 +- tex/context/base/font-col.mkiv | 146 + tex/context/base/font-col.tex | 148 - tex/context/base/font-ctx.lua | 387 + tex/context/base/font-def.lua | 624 +- tex/context/base/font-dum.lua | 113 + tex/context/base/font-enc.lua | 16 +- tex/context/base/font-ext.lua | 304 +- tex/context/base/font-fbk.lua | 102 +- tex/context/base/font-ini.lua | 53 +- tex/context/base/font-ini.mkii | 671 +- tex/context/base/font-ini.mkiv | 2515 ++---- tex/context/base/font-jap.tex | 2 +- tex/context/base/font-log.lua | 53 + tex/context/base/font-map.lua | 32 +- tex/context/base/font-mis.lua | 91 + tex/context/base/font-ota.lua | 320 + tex/context/base/font-otb.lua | 364 + tex/context/base/font-otc.lua | 238 + tex/context/base/font-otd.lua | 78 + tex/context/base/font-otf.lua | 5983 +++----------- tex/context/base/font-oti.lua | 57 + tex/context/base/font-otn.lua | 2496 ++++++ tex/context/base/font-otp.lua | 420 + tex/context/base/font-ott.lua | 935 +++ tex/context/base/font-pat.lua | 53 +- tex/context/base/font-run.tex | 3 +- tex/context/base/font-syn.lua | 417 +- tex/context/base/font-tfm.lua | 977 +-- tex/context/base/font-tra.mkiv | 113 + tex/context/base/font-uni.mkii | 444 ++ tex/context/base/font-uni.mkiv | 26 + tex/context/base/font-uni.tex | 465 -- tex/context/base/font-unk.mkii | 187 + tex/context/base/font-unk.mkiv | 162 + tex/context/base/font-unk.tex | 185 - tex/context/base/font-vf.lua | 72 +- tex/context/base/font-xtx.lua | 115 + tex/context/base/font-xtx.tex | 357 + tex/context/base/hand-ini.mkii | 91 +- tex/context/base/hand-ini.mkiv | 2 +- tex/context/base/hand-ini.tex | 18 - tex/context/base/java-ini.mkii | 713 ++ tex/context/base/java-ini.mkiv | 688 ++ tex/context/base/java-ini.tex | 742 -- tex/context/base/l-aux.lua | 128 +- tex/context/base/l-boolean.lua | 17 +- tex/context/base/l-dimen.lua | 13 +- tex/context/base/l-dir.lua | 447 +- tex/context/base/l-file.lua | 142 +- tex/context/base/l-io.lua | 211 +- tex/context/base/l-lpeg.lua | 58 +- tex/context/base/l-math.lua | 30 +- tex/context/base/l-md5.lua | 78 +- tex/context/base/l-number.lua | 27 +- tex/context/base/l-os.lua | 88 +- tex/context/base/l-set.lua | 87 +- tex/context/base/l-string.lua | 270 +- tex/context/base/l-table.lua | 328 +- tex/context/base/l-unicode.lua | 79 +- tex/context/base/l-url.lua | 54 +- tex/context/base/l-utils.lua | 62 +- tex/context/base/l-xml.lua | 134 +- tex/context/base/lang-alt.tex | 5 +- tex/context/base/lang-ana.tex | 6 +- tex/context/base/lang-ara.tex | 5 +- tex/context/base/lang-art.tex | 6 +- tex/context/base/lang-bal.tex | 6 +- tex/context/base/lang-cel.tex | 6 +- tex/context/base/lang-chi.tex | 6 +- tex/context/base/lang-cjk.tex | 328 + tex/context/base/lang-ctx.tex | 37 +- tex/context/base/lang-cyr.tex | 14 +- tex/context/base/lang-dis.tex | 8 +- tex/context/base/lang-frq.tex | 4 +- tex/context/base/lang-ger.tex | 44 +- tex/context/base/lang-grk.tex | 9 +- tex/context/base/lang-ind.tex | 2 +- tex/context/base/lang-ini.lua | 131 +- tex/context/base/lang-ini.mkii | 588 +- tex/context/base/lang-ini.mkiv | 565 +- tex/context/base/lang-ini.tex | 692 -- tex/context/base/lang-ita.tex | 57 +- tex/context/base/lang-jap.tex | 5 +- tex/context/base/lang-lab.mkii | 295 + tex/context/base/lang-lab.mkiv | 266 + tex/context/base/lang-lab.tex | 284 - tex/context/base/lang-mis.tex | 6 +- tex/context/base/lang-sla.tex | 23 +- tex/context/base/lang-spa.tex | 2 +- tex/context/base/lang-spe.mkii | 244 + tex/context/base/lang-spe.mkiv | 111 + tex/context/base/lang-spe.tex | 242 - tex/context/base/lang-ura.tex | 6 +- tex/context/base/lang-url.lua | 10 +- tex/context/base/lang-url.mkii | 74 + tex/context/base/lang-url.mkiv | 50 +- tex/context/base/lang-url.tex | 70 - tex/context/base/lang-vn.tex | 5 +- tex/context/base/luat-bas.tex | 64 + tex/context/base/luat-cbk.lua | 13 +- tex/context/base/luat-cnf.lua | 114 + tex/context/base/luat-cod.tex | 161 + tex/context/base/luat-crl.lua | 53 - tex/context/base/luat-deb.lua | 154 - tex/context/base/luat-deb.tex | 49 - tex/context/base/luat-dum.lua | 60 + tex/context/base/luat-env.lua | 304 +- tex/context/base/luat-env.tex | 172 - tex/context/base/luat-exe.lua | 13 +- tex/context/base/luat-fio.lua | 81 + tex/context/base/luat-ini.lua | 129 +- tex/context/base/luat-ini.tex | 222 +- tex/context/base/luat-inp.lua | 2300 ------ tex/context/base/luat-iop.lua | 18 +- tex/context/base/luat-kps.lua | 102 - tex/context/base/luat-lib.lua | 174 - tex/context/base/luat-lib.tex | 86 +- tex/context/base/luat-lmx.lua | 141 - tex/context/base/luat-lmx.tex | 16 - tex/context/base/luat-log.lua | 155 - tex/context/base/luat-lua.lua | 2 +- tex/context/base/luat-run.lua | 69 + tex/context/base/luat-soc.lua | 11 + tex/context/base/luat-sta.lua | 44 +- tex/context/base/luat-sto.lua | 134 + tex/context/base/luat-tex.lua | 588 -- tex/context/base/luat-tmp.lua | 433 - tex/context/base/luat-tra.lua | 145 - tex/context/base/luat-tre.lua | 45 - tex/context/base/luat-uni.lua | 21 - tex/context/base/luat-uni.tex | 33 - tex/context/base/luat-zip.lua | 249 - tex/context/base/lxml-ent.lua | 115 + tex/context/base/lxml-ini.lua | 588 +- tex/context/base/lxml-ini.tex | 71 +- tex/context/base/lxml-mis.lua | 106 + tex/context/base/lxml-pth.lua | 1555 ++++ tex/context/base/lxml-tab.lua | 783 ++ tex/context/base/m-arabtex.tex | 2 +- tex/context/base/m-chemic.mkii | 21 + tex/context/base/m-chemic.mkiv | 19 + tex/context/base/m-chemic.tex | 10 +- tex/context/base/m-database.tex | 2 +- tex/context/base/m-educat.tex | 33 - tex/context/base/m-gamma.tex | 230 - tex/context/base/m-mkii.mkiv | 21 + tex/context/base/m-newmat.tex | 14 +- tex/context/base/m-pictex.tex | 11 +- tex/context/base/m-subsub.tex | 47 - tex/context/base/m-timing.tex | 197 +- tex/context/base/m-track.tex | 5 + tex/context/base/m-translate.tex | 6 +- tex/context/base/m-visual.tex | 1 - tex/context/base/math-ali.mkiv | 1059 +++ tex/context/base/math-ams.tex | 4 +- tex/context/base/math-arr.mkii | 391 + tex/context/base/math-arr.mkiv | 439 + tex/context/base/math-def.mkiv | 338 + tex/context/base/math-del.mkiv | 63 + tex/context/base/math-dim.lua | 310 + tex/context/base/math-dis.mkiv | 20 + tex/context/base/math-ext.lua | 143 + tex/context/base/math-ext.tex | 437 - tex/context/base/math-for.mkiv | 73 + tex/context/base/math-frc.mkii | 66 + tex/context/base/math-frc.mkiv | 209 + tex/context/base/math-ini.lua | 637 +- tex/context/base/math-ini.mkii | 679 +- tex/context/base/math-ini.mkiv | 544 +- tex/context/base/math-ini.tex | 688 -- tex/context/base/math-inl.mkiv | 357 + tex/context/base/math-int.mkiv | 87 + tex/context/base/math-lbr.tex | 8 +- tex/context/base/math-map.lua | 365 + tex/context/base/math-mis.tex | 49 - tex/context/base/math-noa.lua | 336 + tex/context/base/math-pln.mkii | 360 + tex/context/base/math-pln.mkiv | 298 + tex/context/base/math-pln.tex | 355 - tex/context/base/math-run.mkii | 97 + tex/context/base/math-run.tex | 95 - tex/context/base/math-scr.mkiv | 215 + tex/context/base/math-tex.tex | 23 +- tex/context/base/math-tim.tex | 106 +- tex/context/base/math-vfu.lua | 1534 ++++ tex/context/base/meta-ini.mkii | 91 +- tex/context/base/meta-ini.mkiv | 431 +- tex/context/base/meta-pdf.lua | 737 +- tex/context/base/meta-pdf.mkii | 936 ++- tex/context/base/meta-pdf.mkiv | 833 +- tex/context/base/meta-pdf.tex | 1020 --- tex/context/base/meta-pdh.lua | 630 ++ tex/context/base/meta-tex.mkii | 2 +- tex/context/base/metatex.tex | 145 + tex/context/base/mlib-ctx.lua | 16 +- tex/context/base/mlib-pdf.lua | 209 +- tex/context/base/mlib-pdf.tex | 6 +- tex/context/base/mlib-pps.lua | 177 +- tex/context/base/mlib-pps.tex | 16 +- tex/context/base/mlib-run.lua | 161 +- tex/context/base/mtx-context-arrange.tex | 105 + tex/context/base/mtx-context-combine.tex | 146 + tex/context/base/mtx-context-ideas.tex | 54 + tex/context/base/mtx-context-listing.tex | 76 + tex/context/base/mtx-context-timing.tex | 46 + tex/context/base/mult-chk.lua | 66 + tex/context/base/mult-chk.mkii | 26 + tex/context/base/mult-chk.mkiv | 103 + tex/context/base/mult-de.tex | 57 + tex/context/base/mult-def.lua | 270 +- tex/context/base/mult-def.tex | 10 +- tex/context/base/mult-en.tex | 57 + tex/context/base/mult-fr.tex | 57 + tex/context/base/mult-his.tex | 19 +- tex/context/base/mult-ini.lua | 31 +- tex/context/base/mult-ini.mkii | 15 +- tex/context/base/mult-ini.mkiv | 34 +- tex/context/base/mult-it.tex | 57 + tex/context/base/mult-mcs.tex | 198 + tex/context/base/mult-mde.tex | 198 + tex/context/base/mult-men.tex | 198 + tex/context/base/mult-mes.lua | 2005 +++++ tex/context/base/mult-mfr.tex | 198 + tex/context/base/mult-mit.tex | 198 + tex/context/base/mult-mnl.tex | 198 + tex/context/base/mult-mno.tex | 198 + tex/context/base/mult-mpe.tex | 198 + tex/context/base/mult-mro.tex | 198 + tex/context/base/mult-nl.tex | 57 + tex/context/base/mult-ro.tex | 57 + tex/context/base/mult-sys.tex | 116 +- tex/context/base/node-dum.lua | 24 + tex/context/base/node-ext.lua | 30 + tex/context/base/node-fin.lua | 363 + tex/context/base/node-fin.tex | 78 + tex/context/base/node-fnt.lua | 206 + tex/context/base/node-ini.lua | 1254 +-- tex/context/base/node-ini.tex | 59 +- tex/context/base/node-inj.lua | 608 ++ tex/context/base/node-par.lua | 2 +- tex/context/base/node-par.tex | 6 +- tex/context/base/node-pro.lua | 155 + tex/context/base/node-res.lua | 110 + tex/context/base/node-seq.lua | 47 +- tex/context/base/node-ser.lua | 274 + tex/context/base/node-shp.lua | 66 + tex/context/base/node-tex.lua | 54 + tex/context/base/node-tra.lua | 399 + tex/context/base/node-tsk.lua | 113 + tex/context/base/node-tst.lua | 108 + tex/context/base/norm-alo.tex | 36 + tex/context/base/norm-ctx.tex | 16 + tex/context/base/norm-etx.tex | 79 + tex/context/base/norm-ltx.tex | 177 + tex/context/base/norm-ptx.tex | 130 + tex/context/base/norm-tex.tex | 351 + tex/context/base/norm-xtx.tex | 18 + tex/context/base/page-app.tex | 4 +- tex/context/base/page-bck.mkii | 593 ++ tex/context/base/page-bck.mkiv | 521 ++ tex/context/base/page-bck.tex | 615 -- tex/context/base/page-flt.tex | 460 +- tex/context/base/page-flw.tex | 4 +- tex/context/base/page-imp.tex | 29 +- tex/context/base/page-ini.mkii | 1555 ++++ tex/context/base/page-ini.mkiv | 1549 ++++ tex/context/base/page-ini.tex | 2034 ----- tex/context/base/page-lay.tex | 5 +- tex/context/base/page-lin.lua | 299 +- tex/context/base/page-lin.mkii | 2 +- tex/context/base/page-lin.mkiv | 16 +- tex/context/base/page-log.tex | 34 +- tex/context/base/page-lyr.tex | 8 +- tex/context/base/page-mak.tex | 9 +- tex/context/base/page-mar.tex | 10 +- tex/context/base/page-mis.tex | 268 + tex/context/base/page-mul.tex | 8 +- tex/context/base/page-not.tex | 2 +- tex/context/base/page-num.tex | 15 +- tex/context/base/page-one.mkii | 659 ++ tex/context/base/page-one.mkiv | 662 ++ tex/context/base/page-one.tex | 659 -- tex/context/base/page-par.tex | 4 +- tex/context/base/page-plg.tex | 4 +- tex/context/base/page-run.tex | 2 +- tex/context/base/page-set.tex | 24 +- tex/context/base/page-sid.tex | 4 +- tex/context/base/page-spr.tex | 2 +- tex/context/base/page-str.tex | 6 +- tex/context/base/page-txt.mkii | 784 ++ tex/context/base/page-txt.mkiv | 808 ++ tex/context/base/page-txt.tex | 784 -- tex/context/base/ppchtex.mkii | 3457 ++++++++ tex/context/base/ppchtex.mkiv | 3359 ++++++++ tex/context/base/ppchtex.tex | 3438 -------- tex/context/base/prop-ini.mkii | 150 + tex/context/base/prop-ini.mkiv | 150 + tex/context/base/prop-ini.tex | 151 - tex/context/base/prop-lay.mkii | 99 + tex/context/base/prop-lay.mkiv | 109 +- tex/context/base/prop-lay.tex | 105 - tex/context/base/prop-mis.mkii | 34 + tex/context/base/prop-mis.mkiv | 34 + tex/context/base/prop-mis.tex | 53 - tex/context/base/prop-run.tex | 39 - tex/context/base/regi-ini.lua | 88 +- tex/context/base/regi-ini.mkii | 167 +- tex/context/base/regi-ini.mkiv | 54 +- tex/context/base/regi-ini.tex | 182 - tex/context/base/regi-syn.tex | 2 +- tex/context/base/regi-utf.tex | 12 +- tex/context/base/s-fnt-01.tex | 4 +- tex/context/base/s-fnt-10.tex | 100 +- tex/context/base/s-fnt-11.tex | 61 + tex/context/base/s-fnt-20.tex | 140 + tex/context/base/s-fnt-21.tex | 46 + tex/context/base/s-fnt-23.tex | 272 + tex/context/base/s-fnt-24.tex | 83 + tex/context/base/s-fnt-25.tex | 162 + tex/context/base/s-fnt-30.tex | 42 + tex/context/base/s-pre-60.tex | 46 +- tex/context/base/s-pre-61.tex | 14 +- tex/context/base/s-pre-62.tex | 20 +- tex/context/base/s-pre-66.tex | 133 + tex/context/base/s-pre-71.tex | 8 +- tex/context/base/s-reg-01.tex | 50 + tex/context/base/scrp-cjk.lua | 576 ++ tex/context/base/scrp-ini.lua | 386 + tex/context/base/scrp-ini.tex | 91 + tex/context/base/sort-def.mkii | 450 -- tex/context/base/sort-def.mkiv | 16 - tex/context/base/sort-def.tex | 432 +- tex/context/base/sort-ini.lua | 135 +- tex/context/base/sort-ini.mkii | 16 +- tex/context/base/sort-ini.mkiv | 8 +- tex/context/base/sort-ini.tex | 32 - tex/context/base/sort-lan.lua | 19 +- tex/context/base/sort-lan.mkii | 203 - tex/context/base/sort-lan.mkiv | 16 - tex/context/base/sort-lan.tex | 189 +- tex/context/base/spec-def.mkii | 20 - tex/context/base/spec-def.mkiv | 23 - tex/context/base/spec-def.tex | 8 +- tex/context/base/spec-dpx.tex | 4 +- tex/context/base/spec-fdf.mkii | 146 - tex/context/base/spec-fdf.mkiv | 31 - tex/context/base/spec-fdf.tex | 205 +- tex/context/base/spec-ini.tex | 154 +- tex/context/base/spec-mis.tex | 26 +- tex/context/base/spec-pdf.lua | 67 - tex/context/base/spec-tpd.mkii | 18 - tex/context/base/spec-tpd.mkiv | 37 - tex/context/base/spec-tpd.tex | 40 +- tex/context/base/spec-var.tex | 2 +- tex/context/base/strc-bkm.lua | 133 + tex/context/base/strc-bkm.tex | 90 + tex/context/base/strc-blk.lua | 145 + tex/context/base/strc-blk.tex | 110 + tex/context/base/strc-def.tex | 302 + tex/context/base/strc-des.lua | 9 + tex/context/base/strc-des.tex | 1018 +++ tex/context/base/strc-doc.lua | 569 ++ tex/context/base/strc-doc.tex | 166 + tex/context/base/strc-flt.lua | 9 + tex/context/base/strc-flt.tex | 2173 +++++ tex/context/base/strc-ini.lua | 276 + tex/context/base/strc-ini.tex | 88 + tex/context/base/strc-itm.lua | 24 + tex/context/base/strc-itm.tex | 1195 +++ tex/context/base/strc-lst.lua | 392 + tex/context/base/strc-lst.tex | 944 +++ tex/context/base/strc-mar.lua | 18 + tex/context/base/strc-mar.tex | 493 ++ tex/context/base/strc-mat.lua | 51 + tex/context/base/strc-mat.tex | 933 +++ tex/context/base/strc-not.lua | 248 + tex/context/base/strc-not.tex | 1154 +++ tex/context/base/strc-num.lua | 457 ++ tex/context/base/strc-num.tex | 440 + tex/context/base/strc-pag.lua | 206 + tex/context/base/strc-pag.tex | 506 ++ tex/context/base/strc-prc.lua | 9 + tex/context/base/strc-prc.tex | 84 + tex/context/base/strc-ref.lua | 875 ++ tex/context/base/strc-ref.tex | 1905 +++++ tex/context/base/strc-reg.lua | 578 ++ tex/context/base/strc-reg.tex | 907 +++ tex/context/base/strc-ren.tex | 467 ++ tex/context/base/strc-sbe.tex | 137 + tex/context/base/strc-sec.tex | 667 ++ tex/context/base/strc-syn.lua | 185 + tex/context/base/strc-syn.tex | 392 + tex/context/base/strc-xml.tex | 87 + tex/context/base/supp-box.tex | 357 +- tex/context/base/supp-dir.mkii | 41 + tex/context/base/supp-dir.mkiv | 21 + tex/context/base/supp-dir.tex | 70 - tex/context/base/supp-eps.tex | 2 +- tex/context/base/supp-fil.lua | 49 +- tex/context/base/supp-fil.mkii | 621 +- tex/context/base/supp-fil.mkiv | 616 +- tex/context/base/supp-fil.tex | 655 -- tex/context/base/supp-fun.tex | 10 +- tex/context/base/supp-ini.tex | 18 - tex/context/base/supp-lan.tex | 4 +- tex/context/base/supp-mat.tex | 13 +- tex/context/base/supp-mis.tex | 3 +- tex/context/base/supp-mpe.tex | 2 +- tex/context/base/supp-mps.tex | 24 +- tex/context/base/supp-mrk.tex | 27 +- tex/context/base/supp-num.tex | 31 +- tex/context/base/supp-pat.tex | 6 +- tex/context/base/supp-pdf.tex | 2 +- tex/context/base/supp-ran.lua | 46 + tex/context/base/supp-ran.mkii | 122 + tex/context/base/supp-ran.mkiv | 30 + tex/context/base/supp-ran.tex | 158 - tex/context/base/supp-spe.tex | 94 +- tex/context/base/supp-tpi.tex | 6 +- tex/context/base/supp-vis.tex | 48 +- tex/context/base/symb-ini.tex | 42 +- tex/context/base/symb-jmn.tex | 1 - tex/context/base/symb-mis.tex | 7 +- tex/context/base/syst-aux.tex | 6841 ++++++++++++++++ tex/context/base/syst-cat.mkii | 61 - tex/context/base/syst-cat.mkiv | 124 - tex/context/base/syst-cat.tex | 517 -- tex/context/base/syst-chr.tex | 131 - tex/context/base/syst-con.lua | 28 +- tex/context/base/syst-con.mkii | 109 +- tex/context/base/syst-con.mkiv | 132 +- tex/context/base/syst-con.tex | 144 - tex/context/base/syst-etx.tex | 298 - tex/context/base/syst-ext.tex | 165 +- tex/context/base/syst-fnt.mkii | 46 + tex/context/base/syst-fnt.mkiv | 46 + tex/context/base/syst-fnt.tex | 43 - tex/context/base/syst-gen.tex | 358 +- tex/context/base/syst-ini.tex | 879 ++ tex/context/base/syst-lua.lua | 91 + tex/context/base/syst-lua.tex | 37 + tex/context/base/syst-mtx.tex | 80 - tex/context/base/syst-new.tex | 21 +- tex/context/base/syst-omg.tex | 79 - tex/context/base/syst-pdt.tex | 50 - tex/context/base/syst-pln.tex | 510 +- tex/context/base/syst-prm.tex | 227 - tex/context/base/syst-rtp.tex | 22 - tex/context/base/syst-str.mkii | 7 +- tex/context/base/syst-str.mkiv | 9 + tex/context/base/syst-str.tex | 40 - tex/context/base/syst-var.tex | 18 - tex/context/base/syst-xtx.tex | 36 - tex/context/base/tabl-ltb.tex | 856 ++ tex/context/base/tabl-ntb.mkii | 1584 ++++ tex/context/base/tabl-ntb.mkiv | 1571 ++++ tex/context/base/tabl-nte.tex | 107 + tex/context/base/tabl-pln.tex | 91 + tex/context/base/tabl-tab.tex | 2507 ++++++ tex/context/base/tabl-tbl.tex | 1435 ++++ tex/context/base/tabl-tsp.tex | 427 + tex/context/base/task-ini.lua | 45 + tex/context/base/task-ini.tex | 22 + tex/context/base/thrd-ran.tex | 4 +- tex/context/base/thrd-tab.tex | 50 +- tex/context/base/thrd-trg.tex | 9 +- tex/context/base/toks-ini.lua | 43 +- tex/context/base/toks-ini.tex | 6 +- tex/context/base/trac-deb.lua | 206 + tex/context/base/trac-deb.tex | 43 + tex/context/base/trac-inf.lua | 149 + tex/context/base/trac-lmx.lua | 158 + tex/context/base/trac-lmx.tex | 16 + tex/context/base/trac-log.lua | 285 + tex/context/base/trac-tim.lua | 163 + tex/context/base/trac-tra.lua | 221 + tex/context/base/type-cow.tex | 4 +- tex/context/base/type-gyr.tex | 252 - tex/context/base/type-ini.mkii | 743 ++ tex/context/base/type-ini.mkiv | 705 ++ tex/context/base/type-ini.tex | 721 -- tex/context/base/type-mac.mkii | 220 + tex/context/base/type-mac.mkiv | 220 + tex/context/base/type-mac.tex | 434 + tex/context/base/type-map.tex | 48 +- tex/context/base/type-one.tex | 494 +- tex/context/base/type-otf.mkii | 535 ++ tex/context/base/type-otf.mkiv | 628 ++ tex/context/base/type-otf.tex | 739 +- tex/context/base/type-siz.mkii | 583 ++ tex/context/base/type-siz.mkiv | 375 + tex/context/base/type-siz.tex | 688 +- tex/context/base/type-syn.tex | 1 - tex/context/base/type-tmf.tex | 103 +- tex/context/base/type-win.tex | 120 + tex/context/base/type-xtx.tex | 2 +- tex/context/base/typo-brk.lua | 186 + tex/context/base/typo-brk.tex | 77 + tex/context/base/typo-cap.lua | 203 + tex/context/base/typo-cap.tex | 214 + tex/context/base/typo-ini.tex | 2 +- tex/context/base/typo-krn.lua | 218 + tex/context/base/typo-krn.tex | 59 + tex/context/base/typo-mir.lua | 409 + tex/context/base/typo-mir.tex | 144 + tex/context/base/typo-spa.lua | 149 + tex/context/base/typo-spa.tex | 69 + tex/context/base/unic-035.tex | 32 + tex/context/base/unic-exp.tex | 4 +- tex/context/base/unic-ini.mkii | 10 +- tex/context/base/unic-ini.mkiv | 19 +- tex/context/base/verb-c.tex | 2 +- tex/context/base/verb-eif.tex | 24 +- tex/context/base/verb-ini.tex | 2 +- tex/context/base/verb-js.tex | 18 +- tex/context/base/verb-jv.tex | 50 +- tex/context/base/verb-lua.lua | 10 +- tex/context/base/verb-mp.lua | 6 +- tex/context/base/verb-mp.tex | 2 +- tex/context/base/verb-pas.tex | 6 +- tex/context/base/verb-pl.tex | 58 +- tex/context/base/verb-sql.tex | 2 +- tex/context/base/verb-tex.lua | 6 +- tex/context/base/verb-tex.tex | 2 +- tex/context/base/verb-xml.tex | 2 +- tex/context/base/x-calcmath.lua | 191 +- tex/context/base/x-cals.mkiv | 15 +- tex/context/base/x-chemml.mkiv | 2 +- tex/context/base/x-ct.mkiv | 2 +- tex/context/base/x-fo.tex | 8 +- tex/context/base/x-mathml.lua | 77 +- tex/context/base/x-mathml.mkiv | 88 +- tex/context/base/x-newcml.tex | 8 +- tex/context/base/x-newmme.tex | 4 +- tex/context/base/x-newmml.mkii | 23 +- tex/context/base/x-newmml.tex | 2 +- tex/context/base/x-newmmo.tex | 2 +- tex/context/base/x-newpml.tex | 2 +- tex/context/base/x-set-02.tex | 11 +- tex/context/base/x-set-11.mkii | 2 +- tex/context/base/x-set-11.mkiv | 2 +- tex/context/base/x-set-11.tex | 2 +- tex/context/base/xetx-chr.tex | 1167 +++ tex/context/base/xetx-cls.tex | 378 + tex/context/base/xetx-ini.tex | 132 + tex/context/base/xetx-utf.tex | 1989 +++++ tex/context/base/xtag-cml.tex | 2 + tex/context/base/xtag-ent.tex | 2 +- tex/context/base/xtag-exp.tex | 6 +- tex/context/base/xtag-ext.tex | 4 +- tex/context/base/xtag-hyp.tex | 6 +- tex/context/base/xtag-ini.mkii | 6 - tex/context/base/xtag-ini.mkiv | 2 - tex/context/base/xtag-ini.tex | 24 +- tex/context/base/xtag-map.tex | 4 +- tex/context/base/xtag-mmc.tex | 8 +- tex/context/base/xtag-mml.tex | 8 +- tex/context/base/xtag-mmp.tex | 31 +- tex/context/base/xtag-pml.tex | 3 +- tex/context/base/xtag-pmu.tex | 4 +- tex/context/base/xtag-pre.tex | 4 +- tex/context/base/xtag-prs.tex | 2 +- tex/context/base/xtag-raw.tex | 6 +- tex/context/base/xtag-rng.tex | 14 +- tex/context/base/xtag-run.tex | 4 +- tex/context/base/xtag-stk.tex | 4 +- tex/context/base/xtag-utf.tex | 6 +- tex/context/bib/bibl-apa-fr.tex | 2 +- tex/context/bib/bibl-apa.tex | 6 +- tex/context/bib/t-bib.mkii | 5 + tex/context/bib/t-bib.mkiv | 64 + tex/context/bib/t-bib.tex | 74 +- tex/context/config/cont-usr.tex | 2 +- tex/context/interface/cont-cs.xml | 32 +- tex/context/interface/cont-cz.xml | 10033 ----------------------- tex/context/interface/cont-de.xml | 32 +- tex/context/interface/cont-en.xml | 32 +- tex/context/interface/cont-fr.xml | 32 +- tex/context/interface/cont-it.xml | 32 +- tex/context/interface/cont-nl.xml | 32 +- tex/context/interface/cont-pe.xml | 32 +- tex/context/interface/cont-ro.xml | 32 +- tex/context/interface/keys-cs.xml | 57 + tex/context/interface/keys-de.xml | 57 + tex/context/interface/keys-en.xml | 57 + tex/context/interface/keys-fr.xml | 57 + tex/context/interface/keys-it.xml | 57 + tex/context/interface/keys-nl.xml | 57 + tex/context/interface/keys-pe.xml | 57 + tex/context/interface/keys-ro.xml | 57 + tex/context/interface/t-bib.xml | 3 + tex/context/patterns/lang-de.hyp | 4 +- tex/context/patterns/lang-de.pat | 5446 +++++++------ tex/context/patterns/lang-de.rme | 8 +- tex/context/patterns/lang-deo.hyp | 4 +- tex/context/patterns/lang-deo.pat | 5446 ++++++------- tex/context/patterns/lang-deo.rme | 8 +- tex/context/patterns/lang-uk.hyp | 8 + tex/context/patterns/lang-uk.pat | 1905 +++++ tex/context/patterns/lang-uk.rme | 70 + tex/context/test/context-test.tex | 27 + tex/context/user/cont-sys.rme | 9 +- tex/generic/context/luatex-basics.tex | 21 + tex/generic/context/luatex-fonts-merged.lua | 11070 ++++++++++++++++++++++++++ tex/generic/context/luatex-fonts.lua | 139 + tex/generic/context/luatex-fonts.tex | 139 + tex/generic/context/luatex-mplib.lua | 469 ++ tex/generic/context/luatex-mplib.tex | 118 + tex/generic/context/luatex-plain.tex | 25 + tex/generic/context/luatex-test.tex | 47 + tex/generic/context/ppchtex.noc | 4 +- 841 files changed, 189804 insertions(+), 102849 deletions(-) create mode 100644 tex/context/base/back-ini.lua create mode 100644 tex/context/base/back-ini.tex create mode 100644 tex/context/base/back-pdf.lua create mode 100644 tex/context/base/back-pdf.tex create mode 100644 tex/context/base/bibl-bib.lua create mode 100644 tex/context/base/bibl-bib.tex create mode 100644 tex/context/base/bibl-tst.lua create mode 100644 tex/context/base/catc-act.tex create mode 100644 tex/context/base/catc-ctx.tex create mode 100644 tex/context/base/catc-def.tex create mode 100644 tex/context/base/catc-ini.lua create mode 100644 tex/context/base/catc-ini.mkii create mode 100644 tex/context/base/catc-ini.mkiv create mode 100644 tex/context/base/catc-sym.tex create mode 100644 tex/context/base/char-enc.lua create mode 100644 tex/context/base/char-enc.tex delete mode 100644 tex/context/base/char-syn.lua create mode 100644 tex/context/base/chem-ini.lua create mode 100644 tex/context/base/chem-ini.mkiv create mode 100644 tex/context/base/chem-str-test.tex create mode 100644 tex/context/base/chem-str.lua create mode 100644 tex/context/base/chem-str.mkiv create mode 100644 tex/context/base/colo-ext.mkii create mode 100644 tex/context/base/colo-ext.mkiv delete mode 100644 tex/context/base/colo-ext.tex create mode 100644 tex/context/base/colo-hex.mkii create mode 100644 tex/context/base/colo-hex.mkiv delete mode 100644 tex/context/base/colo-ini.tex create mode 100644 tex/context/base/context-base.lmx create mode 100644 tex/context/base/context-fonttest.lmx create mode 100644 tex/context/base/context-help.lmx create mode 100644 tex/context/base/context-timing.lmx create mode 100644 tex/context/base/context.rme delete mode 100644 tex/context/base/core-blk.lua delete mode 100644 tex/context/base/core-blk.mkiv delete mode 100644 tex/context/base/core-buf.tex delete mode 100644 tex/context/base/core-con.tex delete mode 100644 tex/context/base/core-ctx.tex create mode 100644 tex/context/base/core-def.mkii create mode 100644 tex/context/base/core-def.mkiv delete mode 100644 tex/context/base/core-def.tex create mode 100644 tex/context/base/core-env.mkii create mode 100644 tex/context/base/core-env.mkiv create mode 100644 tex/context/base/core-fld.mkii create mode 100644 tex/context/base/core-fld.mkiv delete mode 100644 tex/context/base/core-fld.tex create mode 100644 tex/context/base/core-fnt.mkii create mode 100644 tex/context/base/core-fnt.mkiv delete mode 100644 tex/context/base/core-fnt.tex delete mode 100644 tex/context/base/core-inc.tex create mode 100644 tex/context/base/core-int.mkii create mode 100644 tex/context/base/core-int.mkiv delete mode 100644 tex/context/base/core-int.tex delete mode 100644 tex/context/base/core-job.tex delete mode 100644 tex/context/base/core-ltb.tex create mode 100644 tex/context/base/core-mis.mkii create mode 100644 tex/context/base/core-mis.mkiv delete mode 100644 tex/context/base/core-mis.tex create mode 100644 tex/context/base/core-nav.mkii create mode 100644 tex/context/base/core-nav.mkiv delete mode 100644 tex/context/base/core-nav.tex delete mode 100644 tex/context/base/core-new.tex delete mode 100644 tex/context/base/core-ntb.tex delete mode 100644 tex/context/base/core-obj.tex delete mode 100644 tex/context/base/core-pos.tex delete mode 100644 tex/context/base/core-ref.lua delete mode 100644 tex/context/base/core-ref.mkii delete mode 100644 tex/context/base/core-ref.mkiv delete mode 100644 tex/context/base/core-reg.lua delete mode 100644 tex/context/base/core-reg.mkii delete mode 100644 tex/context/base/core-reg.mkiv delete mode 100644 tex/context/base/core-rul.tex delete mode 100644 tex/context/base/core-sec.mkii delete mode 100644 tex/context/base/core-sec.mkiv create mode 100644 tex/context/base/core-sec.tex delete mode 100644 tex/context/base/core-spa.tex delete mode 100644 tex/context/base/core-syn.lua delete mode 100644 tex/context/base/core-syn.mkii delete mode 100644 tex/context/base/core-syn.mkiv delete mode 100644 tex/context/base/core-sys.tex delete mode 100644 tex/context/base/core-tab.tex delete mode 100644 tex/context/base/core-tbl.tex delete mode 100644 tex/context/base/core-tsp.tex delete mode 100644 tex/context/base/core-two.tex delete mode 100644 tex/context/base/core-uti.tex delete mode 100644 tex/context/base/core-ver.tex create mode 100644 tex/context/base/data-aux.lua create mode 100644 tex/context/base/data-bin.lua create mode 100644 tex/context/base/data-con.lua create mode 100644 tex/context/base/data-crl.lua create mode 100644 tex/context/base/data-ctx.lua create mode 100644 tex/context/base/data-gen.lua create mode 100644 tex/context/base/data-inp.lua create mode 100644 tex/context/base/data-kps.lua create mode 100644 tex/context/base/data-lst.lua create mode 100644 tex/context/base/data-lua.lua create mode 100644 tex/context/base/data-out.lua create mode 100644 tex/context/base/data-pre.lua create mode 100644 tex/context/base/data-res.lua create mode 100644 tex/context/base/data-tex.lua create mode 100644 tex/context/base/data-tmf.lua create mode 100644 tex/context/base/data-tmp.lua create mode 100644 tex/context/base/data-tre.lua create mode 100644 tex/context/base/data-use.lua create mode 100644 tex/context/base/data-zip.lua delete mode 100644 tex/context/base/enco-ini.tex delete mode 100644 tex/context/base/enco-pfr.mkii delete mode 100644 tex/context/base/enco-pfr.mkiv delete mode 100644 tex/context/base/enco-utf.tex create mode 100644 tex/context/base/font-chk.lua create mode 100644 tex/context/base/font-cid.lua create mode 100644 tex/context/base/font-col.mkiv delete mode 100644 tex/context/base/font-col.tex create mode 100644 tex/context/base/font-ctx.lua create mode 100644 tex/context/base/font-dum.lua create mode 100644 tex/context/base/font-log.lua create mode 100644 tex/context/base/font-mis.lua create mode 100644 tex/context/base/font-ota.lua create mode 100644 tex/context/base/font-otb.lua create mode 100644 tex/context/base/font-otc.lua create mode 100644 tex/context/base/font-otd.lua create mode 100644 tex/context/base/font-oti.lua create mode 100644 tex/context/base/font-otn.lua create mode 100644 tex/context/base/font-otp.lua create mode 100644 tex/context/base/font-ott.lua create mode 100644 tex/context/base/font-tra.mkiv create mode 100644 tex/context/base/font-uni.mkii create mode 100644 tex/context/base/font-uni.mkiv delete mode 100644 tex/context/base/font-uni.tex create mode 100644 tex/context/base/font-unk.mkii create mode 100644 tex/context/base/font-unk.mkiv delete mode 100644 tex/context/base/font-unk.tex create mode 100644 tex/context/base/font-xtx.lua create mode 100644 tex/context/base/font-xtx.tex delete mode 100644 tex/context/base/hand-ini.tex create mode 100644 tex/context/base/java-ini.mkii create mode 100644 tex/context/base/java-ini.mkiv delete mode 100644 tex/context/base/java-ini.tex create mode 100644 tex/context/base/lang-cjk.tex delete mode 100644 tex/context/base/lang-ini.tex create mode 100644 tex/context/base/lang-lab.mkii create mode 100644 tex/context/base/lang-lab.mkiv delete mode 100644 tex/context/base/lang-lab.tex create mode 100644 tex/context/base/lang-spe.mkii create mode 100644 tex/context/base/lang-spe.mkiv delete mode 100644 tex/context/base/lang-spe.tex delete mode 100644 tex/context/base/lang-url.tex create mode 100644 tex/context/base/luat-bas.tex create mode 100644 tex/context/base/luat-cnf.lua create mode 100644 tex/context/base/luat-cod.tex delete mode 100644 tex/context/base/luat-crl.lua delete mode 100644 tex/context/base/luat-deb.lua delete mode 100644 tex/context/base/luat-deb.tex create mode 100644 tex/context/base/luat-dum.lua delete mode 100644 tex/context/base/luat-env.tex create mode 100644 tex/context/base/luat-fio.lua delete mode 100644 tex/context/base/luat-inp.lua delete mode 100644 tex/context/base/luat-kps.lua delete mode 100644 tex/context/base/luat-lib.lua delete mode 100644 tex/context/base/luat-lmx.lua delete mode 100644 tex/context/base/luat-lmx.tex delete mode 100644 tex/context/base/luat-log.lua create mode 100644 tex/context/base/luat-run.lua create mode 100644 tex/context/base/luat-soc.lua create mode 100644 tex/context/base/luat-sto.lua delete mode 100644 tex/context/base/luat-tex.lua delete mode 100644 tex/context/base/luat-tmp.lua delete mode 100644 tex/context/base/luat-tra.lua delete mode 100644 tex/context/base/luat-tre.lua delete mode 100644 tex/context/base/luat-uni.lua delete mode 100644 tex/context/base/luat-uni.tex delete mode 100644 tex/context/base/luat-zip.lua create mode 100644 tex/context/base/lxml-ent.lua create mode 100644 tex/context/base/lxml-mis.lua create mode 100644 tex/context/base/lxml-pth.lua create mode 100644 tex/context/base/lxml-tab.lua create mode 100644 tex/context/base/m-chemic.mkii create mode 100644 tex/context/base/m-chemic.mkiv delete mode 100644 tex/context/base/m-gamma.tex create mode 100644 tex/context/base/m-mkii.mkiv create mode 100644 tex/context/base/m-track.tex create mode 100644 tex/context/base/math-ali.mkiv create mode 100644 tex/context/base/math-arr.mkii create mode 100644 tex/context/base/math-arr.mkiv create mode 100644 tex/context/base/math-def.mkiv create mode 100644 tex/context/base/math-del.mkiv create mode 100644 tex/context/base/math-dim.lua create mode 100644 tex/context/base/math-dis.mkiv create mode 100644 tex/context/base/math-ext.lua delete mode 100644 tex/context/base/math-ext.tex create mode 100644 tex/context/base/math-for.mkiv create mode 100644 tex/context/base/math-frc.mkii create mode 100644 tex/context/base/math-frc.mkiv delete mode 100644 tex/context/base/math-ini.tex create mode 100644 tex/context/base/math-inl.mkiv create mode 100644 tex/context/base/math-int.mkiv create mode 100644 tex/context/base/math-map.lua delete mode 100644 tex/context/base/math-mis.tex create mode 100644 tex/context/base/math-noa.lua create mode 100644 tex/context/base/math-pln.mkii create mode 100644 tex/context/base/math-pln.mkiv delete mode 100644 tex/context/base/math-pln.tex create mode 100644 tex/context/base/math-run.mkii delete mode 100644 tex/context/base/math-run.tex create mode 100644 tex/context/base/math-scr.mkiv create mode 100644 tex/context/base/math-vfu.lua delete mode 100644 tex/context/base/meta-pdf.tex create mode 100644 tex/context/base/meta-pdh.lua create mode 100644 tex/context/base/metatex.tex create mode 100644 tex/context/base/mtx-context-arrange.tex create mode 100644 tex/context/base/mtx-context-combine.tex create mode 100644 tex/context/base/mtx-context-ideas.tex create mode 100644 tex/context/base/mtx-context-listing.tex create mode 100644 tex/context/base/mtx-context-timing.tex create mode 100644 tex/context/base/mult-chk.lua create mode 100644 tex/context/base/mult-chk.mkii create mode 100644 tex/context/base/mult-chk.mkiv create mode 100644 tex/context/base/mult-mcs.tex create mode 100644 tex/context/base/mult-mde.tex create mode 100644 tex/context/base/mult-men.tex create mode 100644 tex/context/base/mult-mes.lua create mode 100644 tex/context/base/mult-mfr.tex create mode 100644 tex/context/base/mult-mit.tex create mode 100644 tex/context/base/mult-mnl.tex create mode 100644 tex/context/base/mult-mno.tex create mode 100644 tex/context/base/mult-mpe.tex create mode 100644 tex/context/base/mult-mro.tex create mode 100644 tex/context/base/node-dum.lua create mode 100644 tex/context/base/node-ext.lua create mode 100644 tex/context/base/node-fin.lua create mode 100644 tex/context/base/node-fin.tex create mode 100644 tex/context/base/node-fnt.lua create mode 100644 tex/context/base/node-inj.lua create mode 100644 tex/context/base/node-pro.lua create mode 100644 tex/context/base/node-res.lua create mode 100644 tex/context/base/node-ser.lua create mode 100644 tex/context/base/node-shp.lua create mode 100644 tex/context/base/node-tex.lua create mode 100644 tex/context/base/node-tra.lua create mode 100644 tex/context/base/node-tsk.lua create mode 100644 tex/context/base/node-tst.lua create mode 100644 tex/context/base/norm-alo.tex create mode 100644 tex/context/base/norm-ctx.tex create mode 100644 tex/context/base/norm-etx.tex create mode 100644 tex/context/base/norm-ltx.tex create mode 100644 tex/context/base/norm-ptx.tex create mode 100644 tex/context/base/norm-tex.tex create mode 100644 tex/context/base/norm-xtx.tex create mode 100644 tex/context/base/page-bck.mkii create mode 100644 tex/context/base/page-bck.mkiv delete mode 100644 tex/context/base/page-bck.tex create mode 100644 tex/context/base/page-ini.mkii create mode 100644 tex/context/base/page-ini.mkiv delete mode 100644 tex/context/base/page-ini.tex create mode 100644 tex/context/base/page-mis.tex create mode 100644 tex/context/base/page-one.mkii create mode 100644 tex/context/base/page-one.mkiv delete mode 100644 tex/context/base/page-one.tex create mode 100644 tex/context/base/page-txt.mkii create mode 100644 tex/context/base/page-txt.mkiv delete mode 100644 tex/context/base/page-txt.tex create mode 100644 tex/context/base/ppchtex.mkii create mode 100644 tex/context/base/ppchtex.mkiv delete mode 100644 tex/context/base/ppchtex.tex create mode 100644 tex/context/base/prop-ini.mkii create mode 100644 tex/context/base/prop-ini.mkiv delete mode 100644 tex/context/base/prop-ini.tex delete mode 100644 tex/context/base/prop-lay.tex delete mode 100644 tex/context/base/prop-mis.tex delete mode 100644 tex/context/base/prop-run.tex delete mode 100644 tex/context/base/regi-ini.tex create mode 100644 tex/context/base/s-fnt-11.tex create mode 100644 tex/context/base/s-fnt-20.tex create mode 100644 tex/context/base/s-fnt-21.tex create mode 100644 tex/context/base/s-fnt-23.tex create mode 100644 tex/context/base/s-fnt-24.tex create mode 100644 tex/context/base/s-fnt-25.tex create mode 100644 tex/context/base/s-fnt-30.tex create mode 100644 tex/context/base/s-pre-66.tex create mode 100644 tex/context/base/s-reg-01.tex create mode 100644 tex/context/base/scrp-cjk.lua create mode 100644 tex/context/base/scrp-ini.lua create mode 100644 tex/context/base/scrp-ini.tex delete mode 100644 tex/context/base/sort-def.mkii delete mode 100644 tex/context/base/sort-def.mkiv delete mode 100644 tex/context/base/sort-ini.tex delete mode 100644 tex/context/base/sort-lan.mkii delete mode 100644 tex/context/base/sort-lan.mkiv delete mode 100644 tex/context/base/spec-def.mkii delete mode 100644 tex/context/base/spec-def.mkiv delete mode 100644 tex/context/base/spec-fdf.mkii delete mode 100644 tex/context/base/spec-fdf.mkiv delete mode 100644 tex/context/base/spec-pdf.lua delete mode 100644 tex/context/base/spec-tpd.mkii delete mode 100644 tex/context/base/spec-tpd.mkiv create mode 100644 tex/context/base/strc-bkm.lua create mode 100644 tex/context/base/strc-bkm.tex create mode 100644 tex/context/base/strc-blk.lua create mode 100644 tex/context/base/strc-blk.tex create mode 100644 tex/context/base/strc-def.tex create mode 100644 tex/context/base/strc-des.lua create mode 100644 tex/context/base/strc-des.tex create mode 100644 tex/context/base/strc-doc.lua create mode 100644 tex/context/base/strc-doc.tex create mode 100644 tex/context/base/strc-flt.lua create mode 100644 tex/context/base/strc-flt.tex create mode 100644 tex/context/base/strc-ini.lua create mode 100644 tex/context/base/strc-ini.tex create mode 100644 tex/context/base/strc-itm.lua create mode 100644 tex/context/base/strc-itm.tex create mode 100644 tex/context/base/strc-lst.lua create mode 100644 tex/context/base/strc-lst.tex create mode 100644 tex/context/base/strc-mar.lua create mode 100644 tex/context/base/strc-mar.tex create mode 100644 tex/context/base/strc-mat.lua create mode 100644 tex/context/base/strc-mat.tex create mode 100644 tex/context/base/strc-not.lua create mode 100644 tex/context/base/strc-not.tex create mode 100644 tex/context/base/strc-num.lua create mode 100644 tex/context/base/strc-num.tex create mode 100644 tex/context/base/strc-pag.lua create mode 100644 tex/context/base/strc-pag.tex create mode 100644 tex/context/base/strc-prc.lua create mode 100644 tex/context/base/strc-prc.tex create mode 100644 tex/context/base/strc-ref.lua create mode 100644 tex/context/base/strc-ref.tex create mode 100644 tex/context/base/strc-reg.lua create mode 100644 tex/context/base/strc-reg.tex create mode 100644 tex/context/base/strc-ren.tex create mode 100644 tex/context/base/strc-sbe.tex create mode 100644 tex/context/base/strc-sec.tex create mode 100644 tex/context/base/strc-syn.lua create mode 100644 tex/context/base/strc-syn.tex create mode 100644 tex/context/base/strc-xml.tex create mode 100644 tex/context/base/supp-dir.mkii create mode 100644 tex/context/base/supp-dir.mkiv delete mode 100644 tex/context/base/supp-dir.tex delete mode 100644 tex/context/base/supp-fil.tex delete mode 100644 tex/context/base/supp-ini.tex create mode 100644 tex/context/base/supp-ran.lua create mode 100644 tex/context/base/supp-ran.mkii create mode 100644 tex/context/base/supp-ran.mkiv delete mode 100644 tex/context/base/supp-ran.tex create mode 100644 tex/context/base/syst-aux.tex delete mode 100644 tex/context/base/syst-cat.mkii delete mode 100644 tex/context/base/syst-cat.mkiv delete mode 100644 tex/context/base/syst-cat.tex delete mode 100644 tex/context/base/syst-chr.tex delete mode 100644 tex/context/base/syst-con.tex delete mode 100644 tex/context/base/syst-etx.tex create mode 100644 tex/context/base/syst-fnt.mkii create mode 100644 tex/context/base/syst-fnt.mkiv delete mode 100644 tex/context/base/syst-fnt.tex create mode 100644 tex/context/base/syst-ini.tex create mode 100644 tex/context/base/syst-lua.lua create mode 100644 tex/context/base/syst-lua.tex delete mode 100644 tex/context/base/syst-mtx.tex delete mode 100644 tex/context/base/syst-omg.tex delete mode 100644 tex/context/base/syst-pdt.tex delete mode 100644 tex/context/base/syst-prm.tex delete mode 100644 tex/context/base/syst-rtp.tex delete mode 100644 tex/context/base/syst-str.tex delete mode 100644 tex/context/base/syst-var.tex delete mode 100644 tex/context/base/syst-xtx.tex create mode 100644 tex/context/base/tabl-ltb.tex create mode 100644 tex/context/base/tabl-ntb.mkii create mode 100644 tex/context/base/tabl-ntb.mkiv create mode 100644 tex/context/base/tabl-nte.tex create mode 100644 tex/context/base/tabl-pln.tex create mode 100644 tex/context/base/tabl-tab.tex create mode 100644 tex/context/base/tabl-tbl.tex create mode 100644 tex/context/base/tabl-tsp.tex create mode 100644 tex/context/base/task-ini.lua create mode 100644 tex/context/base/task-ini.tex create mode 100644 tex/context/base/trac-deb.lua create mode 100644 tex/context/base/trac-deb.tex create mode 100644 tex/context/base/trac-inf.lua create mode 100644 tex/context/base/trac-lmx.lua create mode 100644 tex/context/base/trac-lmx.tex create mode 100644 tex/context/base/trac-log.lua create mode 100644 tex/context/base/trac-tim.lua create mode 100644 tex/context/base/trac-tra.lua delete mode 100644 tex/context/base/type-gyr.tex create mode 100644 tex/context/base/type-ini.mkii create mode 100644 tex/context/base/type-ini.mkiv delete mode 100644 tex/context/base/type-ini.tex create mode 100644 tex/context/base/type-mac.mkii create mode 100644 tex/context/base/type-mac.mkiv create mode 100644 tex/context/base/type-mac.tex create mode 100644 tex/context/base/type-otf.mkii create mode 100644 tex/context/base/type-otf.mkiv create mode 100644 tex/context/base/type-siz.mkii create mode 100644 tex/context/base/type-siz.mkiv create mode 100644 tex/context/base/type-win.tex create mode 100644 tex/context/base/typo-brk.lua create mode 100644 tex/context/base/typo-brk.tex create mode 100644 tex/context/base/typo-cap.lua create mode 100644 tex/context/base/typo-cap.tex create mode 100644 tex/context/base/typo-krn.lua create mode 100644 tex/context/base/typo-krn.tex create mode 100644 tex/context/base/typo-mir.lua create mode 100644 tex/context/base/typo-mir.tex create mode 100644 tex/context/base/typo-spa.lua create mode 100644 tex/context/base/typo-spa.tex create mode 100644 tex/context/base/unic-035.tex create mode 100644 tex/context/base/xetx-chr.tex create mode 100644 tex/context/base/xetx-cls.tex create mode 100644 tex/context/base/xetx-ini.tex create mode 100644 tex/context/base/xetx-utf.tex delete mode 100644 tex/context/base/xtag-ini.mkii delete mode 100644 tex/context/base/xtag-ini.mkiv create mode 100644 tex/context/bib/t-bib.mkii create mode 100644 tex/context/bib/t-bib.mkiv delete mode 100644 tex/context/interface/cont-cz.xml create mode 100644 tex/context/patterns/lang-uk.hyp create mode 100644 tex/context/patterns/lang-uk.pat create mode 100644 tex/context/patterns/lang-uk.rme create mode 100644 tex/context/test/context-test.tex create mode 100644 tex/generic/context/luatex-basics.tex create mode 100644 tex/generic/context/luatex-fonts-merged.lua create mode 100644 tex/generic/context/luatex-fonts.lua create mode 100644 tex/generic/context/luatex-fonts.tex create mode 100644 tex/generic/context/luatex-mplib.lua create mode 100644 tex/generic/context/luatex-mplib.tex create mode 100644 tex/generic/context/luatex-plain.tex create mode 100644 tex/generic/context/luatex-test.tex (limited to 'tex') 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-- +

This module implements a couple of cleanup methods. We need these +in order to meet the specification. Watch the double +parenthesis; they are needed because otherwise we would pass more +than one argument to .

+--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 {<>}% + \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 <>% + \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 -> <> >> +% object_2 -> <> >> +% rendering -> <> + +\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 + {<>} + +\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 {<>}% + \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 <>}} + +%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{<>}% + \appendtoPDFdocumentextgstates{/GSnegative \PDFobjref\pdflastobj}% + \immediate\pdfobj{<>}% + \appendtoPDFdocumentextgstates{/GSpositive \PDFobjref\pdflastobj}% + \global\let\initializePDFnegative\relax} + +\def\initializePDFoverprint + {\immediate\pdfobj{<>}% /op defaults to /OP + \appendtoPDFdocumentextgstates{/GSknockout \PDFobjref\pdflastobj}% + \immediate\pdfobj{<>}% /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 <>}} + +\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-- +

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.

+--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("\n"), + 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("") + result[#result+1] = format("") + for id, categories in next, session.data do + result[#result+1] = format(" ",id) + for name, entry in next, categories do + if not entries or entries[name] then + result[#result+1] = format(" ",name) + for key, value in next, entry do + value = escaped_pattern:match(value) + if value ~= "" then + result[#result+1] = format(" %s",key,value) + end + end + result[#result+1] = format(" ") + end + end + result[#result+1] = format(" ") + end + result[#result+1] = format("") + 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/catc-sym.tex b/tex/context/base/catc-sym.tex new file mode 100644 index 000000000..49d94815c --- /dev/null +++ b/tex/context/base/catc-sym.tex @@ -0,0 +1,118 @@ +%D \module +%D [ file=catc-sym, +%D version=1997.01.03, % moved code +%D title=\CONTEXT\ Catcode Macros, +%D subtitle=Some Handy Constants, +%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 We want to have access to the raw alternatives of the +%D special characters. We use a \type {\xdef} instead of +%D \type {\let} because we need an expandable token in a +%D \type {\write}. + +\bgroup + +\catcode`B=\@@begingroup +\catcode`E=\@@endgroup +\catcode`.=\@@escape + +.catcode `.{ 12 .xdef .letteropenbrace B.string{E +.catcode `.} 12 .xdef .letterclosebrace B.string}E +.catcode `.& 12 .xdef .letterampersand B.string&E +.catcode `.< 12 .xdef .letterless B.string 12 .xdef .lettermore B.string>E +.catcode `.# 12 .xdef .letterhash B.string#E +.catcode `." 12 .xdef .letterdoublequote B.string"E +.catcode `.' 12 .xdef .lettersinglequote B.string'E +.catcode `.$ 12 .xdef .letterdollar B.string$E +.catcode `.% 12 .xdef .letterpercent B.string%E +.catcode `.^ 12 .xdef .letterhat B.string^E +.catcode `._ 12 .xdef .letterunderscore B.string_E +.catcode `.| 12 .xdef .letterbar B.string|E +.catcode `.~ 12 .xdef .lettertilde B.string~E +.catcode `.\ 12 .xdef .letterbackslash B.string\E +.catcode `./ 12 .xdef .letterslash B.string/E +.catcode `.? 12 .xdef .letterquestionmark B.string?E +.catcode `.! 12 .xdef .letterexclamationmark B.string!E +.catcode `.@ 12 .xdef .letterat B.string@E +.catcode `.: 12 .xdef .lettercolon B.string:E + + .global .let .letterescape .letterbackslash + .global .let .letterbgroup .letteropenbrace + .global .let .letteregroup .letterclosebrace + .global .let .letterleftbrace .letteropenbrace + .global .let .letterrightbrace .letterclosebrace + +.egroup + +%D \macros +%D {uncatcodespecials,setnaturalcatcodes,setnormalcatcodes, +%D uncatcodecharacters,uncatcodeallcharacters, +%D uncatcodespacetokens} +%D +%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} +\def\setnormalcatcodes {\setcatcodetable\ctxcatcodes} % maybe \texcatcodes +\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. This macro is meant for \POSTSCRIPT\ and \PDF\ +%D code passed on to the backend. + +\newtoks\everyverbosechacters + +\def\setverbosecscharacter#1% + {\edef#1{\string#1}} + +\def\setverbosecscharacters + {\the\everyverbosechacters} + +\bgroup + + % 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\/} + +\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="", + description="", direction="l", linebreak="id", unicodeslot=0x3400, - }, - [0x4DB5]={ - category="lo", - cjkwd="w", - description="", - direction="l", - linebreak="id", - unicodeslot=0x4DB5, + range= 0x4DB5, }, [0x4DC0]={ category="so", @@ -83508,17 +84216,11 @@ characters.data={ [0x4E00]={ category="lo", cjkwd="w", - description="", + description="", direction="l", linebreak="id", unicodeslot=0x4E00, - }, - [0x9FBB]={ - category="lo", - cjkwd="w", - description="", - linebreak="id", - unicodeslot=0x9FBB, + range=0x9FBB, }, [0xA000]={ category="lo", @@ -94186,18 +94888,11 @@ characters.data={ [0xAC00]={ category="lo", cjkwd="w", - description="", + description="", direction="l", linebreak="h2", unicodeslot=0xAC00, - }, - [0xD7A3]={ - category="lo", - cjkwd="w", - description="", - 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="", + description="", direction="l", linebreak="id", unicodeslot=0x20000, - }, - [0x2A6D6]={ - category="lo", - cjkwd="w", - description="", - direction="l", - linebreak="id", - unicodeslot=0x2A6D6, + range=0x2A6D6, }, [0x2F800]={ category="lo", diff --git a/tex/context/base/char-enc.lua b/tex/context/base/char-enc.lua new file mode 100644 index 000000000..a4e5ac77d --- /dev/null +++ b/tex/context/base/char-enc.lua @@ -0,0 +1,163 @@ +if not modules then modules = { } end modules ['char-syn'] = { + version = 1.001, + comment = "companion to char-ini.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- thanks to tex4ht for these mappings + +characters = characters or { } + +characters.synonyms = { + angle = 0x2220, + anticlockwise = 0x21BA, + arrowaxisleft = 0x2190, + arrowaxisright = 0x2192, + arrowparrleftright = 0x21C6, + arrowparrrightleft = 0x21C4, + arrowtailleft = 0x21A2, + arrowtailright = 0x21A3, + arrowtripleleft = 0x21DA, + arrowtripleright = 0x21DB, + axisshort = 0x2212, + because = 0x2235, + between = 0x226C, + check = 0x2713, + circleasteris = 0x229B, + circleequal = 0x2257, + circleminus = 0x229D, + circleR = 0x24C7, + circlering = 0x229A, + circleS = 0x24C8, + clockwise = 0x21BB, + complement = 0x2201, + curlyleft = 0x21AB, + curlyright = 0x21AC, + dblarrowdwn = 0x21CA, + dblarrowheadleft = 0x219E, + dblarrowheadright = 0x21A0, + dblarrowleft = 0x21C7, + dblarrowright = 0x21C9, + dblarrowup = 0x21C8, + defines = 0x225C, + diamond = 0x2662, + diamondsolid = 0x2666, + difference = 0x224F, + dotplus = 0x2214, + downfall = 0x22CE, + equaldotleftright = 0x2252, + equaldotrightleft = 0x2253, + equalorfollows = 0x22DF, + equalorgreater = 0x22DD, + equalorless = 0x22DC, + equalorprecedes = 0x22DE, + equalsdots = 0x2251, + followsorcurly = 0x227D, + followsorequal = 0x227F, + forces = 0x22A9, + forcesbar = 0x22AA, + fork = 0x22D4, + frown = 0x2322, + geomequivalent = 0x224E, + greaterdbleqlless = 0x22Da, + greaterdblequal = 0x2267, + greaterlessequal = 0x22DA, + greaterorapproxeql = 0x227F, + greaterorequalslant= 0x2265, + greaterorless = 0x2277, + greaterorsimilar = 0x2273, + harpoondownleft = 0x21C3, + harpoondownright = 0x21C2, + harpoonleftright = 0x21CC, + harpoonrightleft = 0x21CB, + harpoonupleft = 0x21BF, + harpoonupright = 0x21BE, + intercal = 0x22BA, + intersectiondbl = 0x22D2, + lessdbleqlgreater = 0x22DB, + lessdblequal = 0x2266, + lessequalgreater = 0x22DB, + lessorapproxeql = 0x227E, + lessorequalslant = 0x2264, + lessorgreater = 0x2276, + lessorsimilar = 0x2272, + maltesecross = 0xFFFD, + measuredangle = 0x2221, + muchgreater = 0x22D9, + muchless = 0x22D8, + multimap = 0x22B8, + multiopenleft = 0x22CB, + multiopenright = 0x22CC, + nand = 0x22BC, + orunderscore = 0x22BB, + perpcorrespond = 0x2259, + precedesorcurly = 0x227C, + precedesorequal = 0x227E, + primereverse = 0x2035, + proportional = 0x221D, + revasymptequal = 0x2243, + revsimilar = 0x223D, + rightanglene = 0x231D, + rightanglenw = 0x231C, + rightanglese = 0x231F, + rightanglesw = 0x231E, + ringinequal = 0x2256, + satisfies = 0x22A8, + shiftleft = 0x21B0, + shiftright = 0x21B1, + smile = 0x2323, + sphericalangle = 0x2222, + square = 0x25A1, + squaredot = 0x22A1, + squareimage = 0x228F, + squareminus = 0x229F, + squaremultiply = 0x22A0, + squareoriginal = 0x2290, + squareplus = 0x229E, + squaresmallsolid = 0x25AA, + squaresolid = 0x25A0, + squiggleleftright = 0x21AD, + squiggleright = 0x21DD, + star = 0x22C6, + subsetdbl = 0x22D0, + subsetdblequal = 0x2286, + supersetdbl = 0x22D1, + supersetdblequa = 0x2287, + therefore = 0x2234, + triangle = 0x25B5, + triangledownsld = 0x25BE, + triangleinv = 0x25BF, + triangleleft = 0x25C3, + triangleleftequal = 0x22B4, + triangleleftsld = 0x25C2, + triangleright = 0x25B9, + trianglerightequal = 0x22B5, + trianglerightsld = 0x25B8, + trianglesolid = 0x25B4, + uniondbl = 0x22D3, + 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--

This module implements some methods and creates additional datastructured from the big character table that we use for all kind of purposes: char-def.lua.

+ +

We assume that at this point characters.data is already +loaded!

--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--

At this point we assume that the big data table is loaded. From this table we derive a few more.

--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--

The context namespace is used to store methods and data which is rather specific to .

--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--

Instead of using a file to define the named glyphs, we use the table. After all, we have this information available anyway.

--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

Setting the lccodes is also done in a loop over the data table.

--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 @@ -479,22 +511,13 @@ end characters.valid = characters.is_valid ---[[ldx-- -

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.

---ldx]]-- - -function characters.define(c) - characters.data[characters.number(c.unicodeslot)] = c -end - --[[ldx--

--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).

--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.

--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--

Requesting lower and uppercase codes:

--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-- -

The following code is kind of messy. It is used to generate the right -unicode reference tables.

---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-syn.lua b/tex/context/base/char-syn.lua deleted file mode 100644 index a779e1a58..000000000 --- a/tex/context/base/char-syn.lua +++ /dev/null @@ -1,140 +0,0 @@ -if not modules then modules = { } end modules ['char-syn'] = { - version = 1.001, - comment = "companion to char-ini.tex", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- thanks to tex4ht for these mappings - -characters.synonyms = { - angle = 0x2220, - anticlockwise = 0x21BA, - arrowaxisleft = 0x2190, - arrowaxisright = 0x2192, - arrowparrleftright = 0x21C6, - arrowparrrightleft = 0x21C4, - arrowtailleft = 0x21A2, - arrowtailright = 0x21A3, - arrowtripleleft = 0x21DA, - arrowtripleright = 0x21DB, - axisshort = 0x2212, - because = 0x2235, - between = 0x226C, - check = 0x2713, - circleasteris = 0x229B, - circleequal = 0x2257, - circleminus = 0x229D, - circleR = 0x24C7, - circlering = 0x229A, - circleS = 0x24C8, - clockwise = 0x21BB, - complement = 0x2201, - curlyleft = 0x21AB, - curlyright = 0x21AC, - dblarrowdwn = 0x21CA, - dblarrowheadleft = 0x219E, - dblarrowheadright = 0x21A0, - dblarrowleft = 0x21C7, - dblarrowright = 0x21C9, - dblarrowup = 0x21C8, - defines = 0x225C, - diamond = 0x2662, - diamondsolid = 0x2666, - difference = 0x224F, - dotplus = 0x2214, - downfall = 0x22CE, - equaldotleftright = 0x2252, - equaldotrightleft = 0x2253, - equalorfollows = 0x22DF, - equalorgreater = 0x22DD, - equalorless = 0x22DC, - equalorprecedes = 0x22DE, - equalsdots = 0x2251, - followsorcurly = 0x227D, - followsorequal = 0x227F, - forces = 0x22A9, - forcesbar = 0x22AA, - fork = 0x22D4, - frown = 0x2322, - geomequivalent = 0x224E, - greaterdbleqlless = 0x22Da, - greaterdblequal = 0x2267, - greaterlessequal = 0x22DA, - greaterorapproxeql = 0x227F, - greaterorequalslant= 0x2265, - greaterorless = 0x2277, - greaterorsimilar = 0x2273, - harpoondownleft = 0x21C3, - harpoondownright = 0x21C2, - harpoonleftright = 0x21CC, - harpoonrightleft = 0x21CB, - harpoonupleft = 0x21BF, - harpoonupright = 0x21BE, - intercal = 0x22BA, - intersectiondbl = 0x22D2, - lessdbleqlgreater = 0x22DB, - lessdblequal = 0x2266, - lessequalgreater = 0x22DB, - lessorapproxeql = 0x227E, - lessorequalslant = 0x2264, - lessorgreater = 0x2276, - lessorsimilar = 0x2272, - maltesecross = 0xFFFD, - measuredangle = 0x2221, - muchgreater = 0x22D9, - muchless = 0x22D8, - multimap = 0x22B8, - multiopenleft = 0x22CB, - multiopenright = 0x22CC, - nand = 0x22BC, - orunderscore = 0x22BB, - perpcorrespond = 0x2259, - precedesorcurly = 0x227C, - precedesorequal = 0x227E, - primereverse = 0x2035, - proportional = 0x221D, - revasymptequal = 0x2243, - revsimilar = 0x223D, - rightanglene = 0x231D, - rightanglenw = 0x231C, - rightanglese = 0x231F, - rightanglesw = 0x231E, - ringinequal = 0x2256, - satisfies = 0x22A8, - shiftleft = 0x21B0, - shiftright = 0x21B1, - smile = 0x2323, - sphericalangle = 0x2222, - square = 0x25A1, - squaredot = 0x22A1, - squareimage = 0x228F, - squareminus = 0x229F, - squaremultiply = 0x22A0, - squareoriginal = 0x2290, - squareplus = 0x229E, - squaresmallsolid = 0x25AA, - squaresolid = 0x25A0, - squiggleleftright = 0x21AD, - squiggleright = 0x21DD, - star = 0x22C6, - subsetdbl = 0x22D0, - subsetdblequal = 0x2286, - supersetdbl = 0x22D1, - supersetdblequa = 0x2287, - therefore = 0x2234, - triangle = 0x25B5, - triangledownsld = 0x25BE, - triangleinv = 0x25BF, - triangleleft = 0x25C3, - triangleleftequal = 0x22B4, - triangleleftsld = 0x25C2, - triangleright = 0x25B9, - trianglerightequal = 0x22B5, - trianglerightsld = 0x25B8, - trianglesolid = 0x25B4, - uniondbl = 0x22D3, - uprise = 0x22CF, - Yen = 0x00A5, -} 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 ).

over a string.

--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--

It only makes sense to collapse at runtime, since we don't expect -source code to depend on collapsing:

- - -characters.filters.utf.collapsing = true -input.filters.utf_translator = characters.filters.utf.collapse - +source code to depend on collapsing.

--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--

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-- -

In the beginning of 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.

- - -utffilters.collapsing = true -characters.filters.append(utffilters.collapse) -characters.filters.activated = true -callback.register('process_input_buffer', characters.filters.process) - - -

The following helper functions may disappear (or become optional) -in the future. Well, they are now.

+

Next we implement some commands that are used in the user interface.

--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-- -

The following code is no longer needed and replaced by token -collectors somehwere else.

+

A few helpers (used to be luat-uni).

--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 { } + +--[[ +

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.

+]]-- + +-- 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.mkii b/tex/context/base/colo-ext.mkii new file mode 100644 index 000000000..06facd34e --- /dev/null +++ b/tex/context/base/colo-ext.mkii @@ -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-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-ext.tex b/tex/context/base/colo-ext.tex deleted file mode 100644 index 33e87459d..000000000 --- a/tex/context/base/colo-ext.tex +++ /dev/null @@ -1,57 +0,0 @@ -%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 @@ + + + + + + + + + <?lua pv('title') ?> + + + + +
+ +
+
+ +
+ +
+
+
+
+ +
+ + 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 @@ - - - <?lua pv('title') ?> - - - + + + + + <?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 @@ - - - <?lua pv('title') ?> - - - + + + + <?lua pv('title') ?> + + +
@@ -41,7 +46,6 @@ -

Scratch Variables

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 @@ - - - <?lua pv('title')?> - - - + + + + <?lua pv('title')?> + + +
@@ -40,7 +44,7 @@ File     Line     -
+
             
             
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 @@ + + + + + + + + + + <?lua pv('title')?> + + + + +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ + 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 @@ + + + + + + + + + + <?lua pv('title') ?> + + + + +
+ +
+
+ +
+ +
+
+ +
+
+

+ +
+
+
+ +
+ + 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 @@ + + + + + + + + + + + + <?lua pv('title')?> + + + + +
+ +
+
+ +
+ +
+ +
+
+ +

+ +
+ +
+
+ + 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.lua b/tex/context/base/core-blk.lua deleted file mode 100644 index 1007273d5..000000000 --- a/tex/context/base/core-blk.lua +++ /dev/null @@ -1,145 +0,0 @@ -if not modules then modules = { } end modules ['core-blk'] = { - version = 1.001, - comment = "companion to core-blk.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- this one runs on top of buffers and structure - -local texprint, format = tex.print, string.format - -structure = structure or { } -structure.blocks = structure.blocks or { } - -local blocks = structure.blocks - -blocks.collected = blocks.collected or { } -blocks.tobesaved = blocks.tobesaved or { } -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 -end - --- not used, todo: option to do single or double pass - --- job.register('structure.blocks.collected', structure.blocks.tobesaved, initializer, nil) - -local printer = (lpeg.linebyline/texprint)^0 - -function blocks.print(name,data,hide) - if hide then - texprint(tex.ctxcatcodes,format("\\dostarthiddenblock{%s}",name)) - else - texprint(tex.ctxcatcodes,format("\\dostartnormalblock{%s}",name)) - end - if type(data) == "table" then - for i=1,#data do - texprint(data[i]) - end - else - printer:match(data) - end - if hide then - texprint(tex.ctxcatcodes,"\\dostophiddenblock") - else - texprint(tex.ctxcatcodes,"\\dostopnormalblock") - end -end - -function blocks.define(name) - states[name] = { all = "hide" } -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 - local sn = states[n] - if not sn then - -- error - elseif all then - sn.all = state - else - for _, tag in pairs(tags) do - sn[tag] = state - end - end - end -end - -function blocks.select(state,name,tag,criterium) - criterium = criterium or "text" - if tag:find("=") then tag = "" end - local names = aux.settings_to_set(name) - local all = tag == "" - 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) - for i=1,#result do - local b = result[i].entry - if names[b.name] then - local btags = b.tags - if all then - blocks.print(name,b.data,hide) - else - for tag, sta in pairs(tags) do - if btags[tag] then - blocks.print(name,b.data,hide) - break - end - end - end - end - end -end - -function blocks.save(name,tag,buffer) - 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 = { - name = name, - tags = tags, - data = data or "error", - plus = plus, - minus = minus, - }, - sectionnumber = slt[#slt] and slt[#slt].sectionnumber - } - local allstate = states[name].all - if not next(tags) then - if allstate ~= "hide" then - blocks.print(name,data) - elseif plus then - blocks.print(name,data,true) - end - else - local sn = states[name] - for tag, _ in pairs(tags) do - if sn[tag] == nil then - if allstate ~= "hide" then - blocks.print(name,data) - break - end - elseif sn[tag] ~= "hide" then - blocks.print(name,data) - break - end - end - 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/core-blk.mkiv deleted file mode 100644 index 9d1f4deb4..000000000 --- a/tex/context/base/core-blk.mkiv +++ /dev/null @@ -1,109 +0,0 @@ -%D \module -%D [ file=core-blk, -%D version=2008.10.20, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Blockmoves, -%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-blk}{1.001} -\ctxloadluafile{core-blk}{} - -% we run on top of buffers and sections -% -% todo: prefix numbers (needs further integration elsewhere) -% check functionality -% alternative files (needs further integration elsewhere) - -\def\blockparameter#1#2{\ifcsname\??tb#1#2\endcsname\csname\??tb#1#2\endcsname\fi} - -\def\setupblockparameters{\dodoubleargument \dosetupblock} % fast one (for compatibility) -\def\setupblock {\dodoubleargumentwithset\dosetupblock} % handles set - -\def\dosetupblock[#1]{\getparameters[\??tb#1]} % [#1][#2]} - -\def\defineblock - {\dosingleargument\dodefineblock} - -\def\dodefineblock[#1]% - {\getparameters - [\??tb#1] - [\c!before=\blank, - \c!after=\blank, - \c!inner=, - \c!style=, - \c!file=]% todo - \ctxlua{structure.blocks.define("#1")}% - \setvalue{\e!begin#1}{\dodoubleempty\dobeginofblock[#1]}% - \letvalue{\e!end#1}\relax} - -\long\def\dobeginofblock[#1][#2]% - {\expanded{\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}} - {}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after - -\def\dostarthiddenblock - {\startnointerference - \dostartnormalblock} - -\def\dostophiddenblock - {\dostopnormalblock - \stopnointerference} - -% order matters: \c!before (think of: \c!before=\startitemize) - -\let\doblocksetups\gobbleoneargument - -\def\dostartnormalblock#1% name - {\bgroup -\visibletrue - \edef\currentblock{#1}% - \doblocksetups\currentblock - \let\doblocksetups\gobbleoneargument - \blockparameter\currentblock\c!before - \dosetfontattribute{\??tb\currentblock}\c!style - \dosetcolorattribute{\??tb\currentblock}\c!color - \blockparameter\currentblock\c!inner - \ignorespaces} - -\def\dostopnormalblock - {\removeunwantedspaces - \blockparameter\currentblock\c!after - \par % todo: alternative = text, paragraph - \egroup} - -\def\dosetblockstate[#1][#2][#3]% state name tag - {\ctxlua{structure.blocks.setstate("#1","#2","#3")}} - -\def\doselectblocks[#1][#2][#3][#4]% state name tag setups - {\begingroup - \doifassignmentelse{#3} - {\getparameters[\??tb\??tb][\c!criterium=\v!text,#3]% - \def\doblocksetups##1{\getparameters[\??tb##1][#3]}% - \ctxlua{structure.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} - {\getparameters[\??tb\??tb][\c!criterium=\v!text,#4]% - \def\doblocksetups##1{\getparameters[\??tb##1][#4]}% - \ctxlua{structure.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% - \endgroup} - -% hide: save, if [+] also hidden execute -% keep: save and normal execute - -\def\hideblocks{\dotripleempty\dosetblockstate[hide]} -\def\keepblocks{\dotripleempty\dosetblockstate[keep]} - -% use : normal execute unless [-] -% process: hidden execute unless [-] -% select : idem use - -\def\useblocks {\doquadrupleempty\doselectblocks[use]} -\def\processblocks{\doquadrupleempty\doselectblocks[process]} -\def\selectblocks {\doquadrupleempty\doselectblocks[use]} - -\protect 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.

Some code may move to a module in the language namespace.

--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-env.mkii b/tex/context/base/core-env.mkii new file mode 100644 index 000000000..a22594b27 --- /dev/null +++ b/tex/context/base/core-env.mkii @@ -0,0 +1,543 @@ +%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 + +% 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\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{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % {..} +\def\dosetupsB[#1]{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % [..] +\def\dosetupsC[#1]{\cleanuplabel{#1}\dosetups\cleanlabel} % [..] + +% \def\dosetups#1% the grid option will be extended to other main modes +% {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} +% {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument +% +% \def\setupwithargument#1% the grid option will be extended to other main modes +% {\executeifdefined{\??su:#1}\gobbleoneargument} + +% better: + +% \def\dosetups#1% the grid option will be extended to other main modes +% {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} +% {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument +% +% \def\setupwithargument#1% the grid option will be extended to other main modes +% {\executeifdefined{\??su:#1}\gobbleoneargument} + +% faster: + +\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 + +% somehow fails ... +% +% \letvalue{\??su:..}\gobbleoneargument +% +% \def\dosetups#1% the grid option will be extended to other main modes +% {\csname \??su +% \ifcsname\??su\ifgridsnapping\v!grid\fi:#1\endcsname\v!grid:#1\else +% \ifcsname\??su :#1\endcsname :#1\else +% :..\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..\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\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 + \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% watch out: not \grabuntil +% {\dograbuntil#1{\endgroup\dodoglobal\long\setvalue{\??su#2:#3}}} % \doglobal +% +% better: + +% \long\def\dodostartsetups#1#2#3% watch out: not \grabuntil +% {\cleanuplabel{\??su#2:#3}\dograbuntil#1{\endgroup\dodoglobal\long\setvalue\cleanlabel}} % \doglobal + +% \long\def\dodostartsetups#1#2#3% +% {\cleanuplabel{\??su#2:#3}% +% \long\def\dododostartsetups##1#1{\endgroup\dodoglobal\long\setvalue\cleanlabel####1{##1}}\dododostartsetups} + +\long\def\dodostartsetups#1#2#3% + {\cleanuplabel{\??su#2:#3}% + \long\def\dododostartsetups##1#1% + {\endgroup + \dodoglobal % bah + \long\expandafter\setvalue\expandafter\cleanlabel\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 + {\ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}% + \dodoglobal\letbeundefined{\??su:#1}% + \else + \dodoglobal\letbeundefined{\??su\ifgridsnapping\v!grid\fi:#1}% + \fi} + +% or +% +% \def\resetsetups[#1]% +% {\letbeundefined +% {\??su:% +% \ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}#1\else\ifgridsnapping\v!grid\fi% +% #1}} + +%D new and beta and will become a module instead + +\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} % + \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 \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 test +%D test test +%D test test +%D test test +%D zus<>zo zus<:>zo zus<::>zo +%D test test dat (ziezo) +%D test test dat (:ziezo) +%D test test dat (ziezo:) +%D test test dat (zi:ezo:) +%D well, 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 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 + +%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 +% \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 + +\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-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 test +%D test test +%D test test +%D test test +%D zus<>zo zus<:>zo zus<::>zo +%D test test dat (ziezo) +%D test test dat (:ziezo) +%D test test dat (ziezo:) +%D test test dat (zi:ezo:) +%D well, 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 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.mkii b/tex/context/base/core-fld.mkii new file mode 100644 index 000000000..2b177c916 --- /dev/null +++ b/tex/context/base/core-fld.mkii @@ -0,0 +1,1080 @@ +%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% + {\checkobjectreferences + \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-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-fld.tex b/tex/context/base/core-fld.tex deleted file mode 100644 index 3b1ce9b3f..000000000 --- a/tex/context/base/core-fld.tex +++ /dev/null @@ -1,1080 +0,0 @@ -%D \module -%D [ file=core-fld, -%D version=1997.05.18, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Fill in 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 Field Macros} - -% 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% - {\checkobjectreferences - \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.mkii b/tex/context/base/core-fnt.mkii new file mode 100644 index 000000000..9bc2a66f5 --- /dev/null +++ b/tex/context/base/core-fnt.mkii @@ -0,0 +1,726 @@ +%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 {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}. + +\def\usepseudocaps + {\def\cap@@uppercase{\the\everyuppercase\uppercased}% + \def\cap@@lowercase{\the\everylowercase\lowercased}% + \def\cap@@visualize{\tx}} + +\def\userealcaps + {\let\cap@@uppercase\relax + %\let\cap@@lowercase\relax % Definitely not! + \def\cap@@visualize{\sc}} + +\usepseudocaps + +\unexpanded\def\smallcapped % else conflict with math + {\futurelet\next\dosmallcapped} + +\def\disablepseudocaps + {\let\smallcapped\donothing} + +\def\dosmallcapped + {\ifx\next\bgroup + \expandafter\dodosmallcapped\expandafter\relax + \else + \expandafter\dodosmallcapped + \fi} + +\def\dodosmallcapped#1#2% + {\ifmmode\hbox\fi + \bgroup + \cap@@visualize + \cap@@uppercase{#1{#2}}% + \egroup} + +\unexpanded\def\notsmallcapped#1% + {\cap@@lowercase{#1}} + +\unexpanded\def\CAPPED#1% + {{\def\\##1{\smallcapped{##1}}#1}} + +\unexpanded\def\SmallCapped#1% + {\CAPPED{\\#1}} + +\unexpanded\def\SmallCaps + {\let\processword\SmallCapped + \processwords} + +%D Sure: + +\def\kap{\smallcapped} % for old times sake + +%D Some precautions for a \PLAIN\ \TEX\ definition. + +\unexpanded\def\normalcap{\dohandlemathtoken{cap}} +\unexpanded\def\normalCap{\dohandlemathtoken{Cap}} + +\def\cap{\mathortext\normalcap\smallcapped} +\def\Cap{\mathortext\normalCap\SmallCapped} + +\appendtoks + \let\cap\firstofoneargument + \let\Cap\firstofoneargument +\to \simplifiedcommands + +%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]% + \unexpanded\def\smallcapped{\normalsmallcapped}} + {\definealternativestyle[\v!capital][\normalsmallcapped][\uppercased]% + \definealternativestyle[\v!smallcaps][\sc][\uppercased]% + \unexpanded\def\smallcapped{\doconvertfont\v!capital}}% + \doifelse\@@kksc\v!yes + \userealcaps + \usepseudocaps} + +\ifx\uppercased\undefined \let\uppercased\uppercase \fi +\ifx\lowercased\undefined \let\lowercased\lowercase \fi + +% pretty tricky stuff: +% +% \usemodule[abr-01] \TEX \METAPOST \PPCHTEX \LATEX +% \usemodule[abr-02] \TEX \METAPOST \PPCHTEX \LATEX + +%def\uppercased#1{{\forceunexpanded\xdef\@@globalcrap{\uppercase{#1}}}\@@globalcrap} +%def\lowercased#1{{\forceunexpanded\xdef\@@globalcrap{\lowercase{#1}}}\@@globalcrap} + +\def\uppercased#1{{\forceunexpanded\xdef\@@expanded{\uppercase{#1}}}\@@expanded} +\def\lowercased#1{{\forceunexpanded\xdef\@@expanded{\lowercase{#1}}}\@@expanded} + +\setupcapitals + [\c!title=\v!yes, + \c!sc=\v!no] + +%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\doWord#1% + {\bgroup + \the\everyuppercase + \uppercase{#1}% + \egroup} + +\unexpanded\def\Word#1% + {\doWord#1} + +\def\doprocesswords#1 #2\od + {\ConvertToConstant\doifnot{#1}{} + {\processword{#1} % + \doprocesswords#2 \od}} + +\def\processwords#1% + {\doprocesswords#1 \od\unskip} + +\let\processword\relax + +\unexpanded\def\Words + {\let\processword\Word + \processwords} + +\unexpanded\def\WORD#1% + {\bgroup + \let\smallcapped\firstofoneargument + \let\WORD\firstofoneargument + \douppercase{#1}% + \egroup} + +\unexpanded\def\WORDS#1% + {\WORD{#1}} + +%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} +%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#1#2% +% {\dontleavehmode +% \hbox +% {\setbox4=\hbox{\dohighlow\lower\mathsubnormal{.48}{.1}{#1}}% +% \setbox6=\hbox{\dohighlow\raise\mathsupnormal{.86}{.1}{#2}}% +% \ifdim\wd4<\wd6 +% \wd4=\zeropoint\box4\box6 +% \else +% \wd6=\zeropoint\box6\box4 +% \fi}} + +\unexpanded\def\lohi + {\dosingleempty\dolohi} + +\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}} + +%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-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-fnt.tex b/tex/context/base/core-fnt.tex deleted file mode 100644 index e6f7fada4..000000000 --- a/tex/context/base/core-fnt.tex +++ /dev/null @@ -1,726 +0,0 @@ -%D \module -%D [ file=core-fnt, -%D version=1995.10.10, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Font 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. - -\writestatus{loading}{Context Core Macros / Font Support} - -\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 {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}. - -\def\usepseudocaps - {\def\cap@@uppercase{\the\everyuppercase\uppercased}% - \def\cap@@lowercase{\the\everylowercase\lowercased}% - \def\cap@@visualize{\tx}} - -\def\userealcaps - {\let\cap@@uppercase\relax - %\let\cap@@lowercase\relax % Definitely not! - \def\cap@@visualize{\sc}} - -\usepseudocaps - -\unexpanded\def\smallcapped % else conflict with math - {\futurelet\next\dosmallcapped} - -\def\disablepseudocaps - {\let\smallcapped\donothing} - -\def\dosmallcapped - {\ifx\next\bgroup - \expandafter\dodosmallcapped\expandafter\relax - \else - \expandafter\dodosmallcapped - \fi} - -\def\dodosmallcapped#1#2% - {\ifmmode\hbox\fi - \bgroup - \cap@@visualize - \cap@@uppercase{#1{#2}}% - \egroup} - -\unexpanded\def\notsmallcapped#1% - {\cap@@lowercase{#1}} - -\unexpanded\def\CAPPED#1% - {{\def\\##1{\smallcapped{##1}}#1}} - -\unexpanded\def\SmallCapped#1% - {\CAPPED{\\#1}} - -\unexpanded\def\SmallCaps - {\let\processword\SmallCapped - \processwords} - -%D Sure: - -\def\kap{\smallcapped} % for old times sake - -%D Some precautions for a \PLAIN\ \TEX\ definition. - -\unexpanded\def\normalcap{\dohandlemathtoken{cap}} -\unexpanded\def\normalCap{\dohandlemathtoken{Cap}} - -\def\cap{\mathortext\normalcap\smallcapped} -\def\Cap{\mathortext\normalCap\SmallCapped} - -\appendtoks - \let\cap\firstofoneargument - \let\Cap\firstofoneargument -\to \simplifiedcommands - -%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]% - \unexpanded\def\smallcapped{\normalsmallcapped}} - {\definealternativestyle[\v!capital][\normalsmallcapped][\uppercased]% - \definealternativestyle[\v!smallcaps][\sc][\uppercased]% - \unexpanded\def\smallcapped{\doconvertfont\v!capital}}% - \doifelse\@@kksc\v!yes - \userealcaps - \usepseudocaps} - -\ifx\uppercased\undefined \let\uppercased\uppercase \fi -\ifx\lowercased\undefined \let\lowercased\lowercase \fi - -% pretty tricky stuff: -% -% \usemodule[abr-01] \TEX \METAPOST \PPCHTEX \LATEX -% \usemodule[abr-02] \TEX \METAPOST \PPCHTEX \LATEX - -%def\uppercased#1{{\forceunexpanded\xdef\@@globalcrap{\uppercase{#1}}}\@@globalcrap} -%def\lowercased#1{{\forceunexpanded\xdef\@@globalcrap{\lowercase{#1}}}\@@globalcrap} - -\def\uppercased#1{{\forceunexpanded\xdef\@@expanded{\uppercase{#1}}}\@@expanded} -\def\lowercased#1{{\forceunexpanded\xdef\@@expanded{\lowercase{#1}}}\@@expanded} - -\setupcapitals - [\c!title=\v!yes, - \c!sc=\v!no] - -%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\doWord#1% - {\bgroup - \the\everyuppercase - \uppercase{#1}% - \egroup} - -\unexpanded\def\Word#1% - {\doWord#1} - -\def\doprocesswords#1 #2\od - {\ConvertToConstant\doifnot{#1}{} - {\processword{#1} % - \doprocesswords#2 \od}} - -\def\processwords#1% - {\doprocesswords#1 \od\unskip} - -\let\processword\relax - -\unexpanded\def\Words - {\let\processword\Word - \processwords} - -\unexpanded\def\WORD#1% - {\bgroup - \let\smallcapped\firstofoneargument - \let\WORD\firstofoneargument - \douppercase{#1}% - \egroup} - -\unexpanded\def\WORDS#1% - {\WORD{#1}} - -%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} -%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#1#2% -% {\dontleavehmode -% \hbox -% {\setbox4=\hbox{\dohighlow\lower\mathsubnormal{.48}{.1}{#1}}% -% \setbox6=\hbox{\dohighlow\raise\mathsupnormal{.86}{.1}{#2}}% -% \ifdim\wd4<\wd6 -% \wd4=\zeropoint\box4\box6 -% \else -% \wd6=\zeropoint\box6\box4 -% \fi}} - -\unexpanded\def\lohi - {\dosingleempty\dolohi} - -\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}} - -%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.mkii b/tex/context/base/core-int.mkii new file mode 100644 index 000000000..1ca9d23d1 --- /dev/null +++ b/tex/context/base/core-int.mkii @@ -0,0 +1,2217 @@ +%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} + +%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} + +\def\@@bookmark {bm::} +\def\@@booklevel{bl::} +\def\@@bookcount{bc::} + +\definelist[\@@bookmark] + +\newtoks\postponedbookmarks + +\def\flushpostponedbookmark + {\the\postponedbookmarks + \global\postponedbookmarks\emptytoks} + +\def\simplebookmark#1% + {\doglobal\prependtoks + \writetolist[\@@bookmark]{}{#1}% + \to\postponedbookmarks} + +\def\complexbookmark[#1]#2% + {\doglobal\appendtoks\writetolist[#1]{}{#2}\to\postponedbookmarks} + +\definecomplexorsimple\bookmark + +\newif\iftracebookmarks \tracebookmarksfalse + +\let\tracebookmarks\tracebookmarkstrue + +\def\placebookmarks + {\dodoubleempty\doplacebookmarks} + +\def\doplacebookmarks[#1][#2]% + {\iflocation + \iffirstargument + \bgroup + \ifsecondargument + \doifelse{#2}\v!all + {\edef\openbookmarklist{#1}} + {\edef\openbookmarklist{#2}}% + \else + \let\openbookmarklist\empty + \fi + \global\let\bookmarklevellist\empty + \def\bookmarklevelcount{0}% + \doprocessbookmarks[#1]\dogetbookmarkelement + \dolistelement{}{}{}{}{}{}% needed to finish the first pass + \doprocessbookmarks[#1]\doputbookmarkelement + \flushbookmark + \egroup + \else + \expanded{\placebookmarks\@EA[\getvalue{\??ih\v!content\c!list}]}% + \fi + \fi} + +\def\doprocessbookmarks[#1]#2% + {\let\dolistelement#2\relax + \scratchcounter\zerocount + \def\docommand##1% + {\advance\scratchcounter \plusone + \getlistlevel[##1]\listlevel{\the\scratchcounter}% + \setxvalue{\@@bookcount\the\scratchcounter}{1}% + \setxvalue{\@@booklevel##1}{\listlevel}}% + \processcommalist[#1]\docommand + \setxvalue{\@@bookcount0}{1}% + \global\chardef\currentbookmarklevel\zerocount + \global\chardef\previousbookmarklevel\zerocount + \doutilities{listentries,#1,\@@bookmark}\jobname{#1}\relax\relax} + +\def\dodogetbookmarkelement#1#2#3#4#5#6% + {\doifelsenothing{#1} + {\global\chardef\currentbookmarklevel\zerocount} + {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% + \ifnum\currentbookmarklevel>\previousbookmarklevel + \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% + \else\ifnum\currentbookmarklevel<\previousbookmarklevel + \bgroup + \!!counta\previousbookmarklevel + \doloop + {\let\bookmarktag\empty + \!!countb\!!counta + \advance\!!countb \minusone + \dorecurse\!!countb + {\edef\bookmarktag + {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% + \edef\bookmarklevelcount + {\getvalue{\@@bookcount\the\!!counta}}% + \xdef\bookmarklevellist + {\bookmarklevellist/\bookmarktag:\bookmarklevelcount/}% + \advance\!!counta \minusone + \ifnum\!!counta=\currentbookmarklevel + \exitloop + \fi}% + \egroup + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax + \else + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax + \fi\fi + \global\utilitydonetrue + \global\chardef\previousbookmarklevel\currentbookmarklevel} + +\def\getbookmarklevelcount + {\@EA\def\@EA\docommand\@EA[\@EA##\@EA1\@EA/\bookmarktag:##2/##3]% + {\def\bookmarklevelcount{##2}}% + \@EA\@EA\@EA\docommand\@EA\@EA\@EA[\@EA\bookmarklevellist\@EA/\bookmarktag:0/]} + +\def\dodoputbookmarkelement#1#2#3#4#5#6% + {\doifelsenothing{#1} + {\global\chardef\currentbookmarklevel\zerocount} + {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% + \ifnum\currentbookmarklevel>\previousbookmarklevel + \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% + \else\ifnum\currentbookmarklevel<\previousbookmarklevel + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax + \else + \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax + \fi\fi + \let\bookmarktag\empty + \!!countb\currentbookmarklevel + \dorecurse\!!countb + {\edef\bookmarktag + {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% + \getbookmarklevelcount + \iftracebookmarks + \bgroup + \par + \bookmarktag\quad + \dorecurse\currentbookmarklevel{\quad}\unskip#1\quad + (\bookmarklevelcount)\quad + \egroup + \fi + \global\chardef\previousbookmarklevel\currentbookmarklevel + \global\utilitydonetrue + \insertsomebookmark{#1}{\the\currentbookmarklevel}{\bookmarklevelcount}{#4}{#6}} + +\def\dogetbookmarkelement#1#2#3#4#5#6% + {\doifnot{#1}\@@bookmark + {\dodogetbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\doputbookmarkelement#1#2#3#4#5#6% + {\doifelse{#1}\@@bookmark + {\localbookmark{#4}} + {\flushbookmark + \dodoputbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} + +\let\flushbookmark\relax +\let\localbookmark\gobbleoneargument + +\def\insertsomebookmark#1#2#3#4#5% + {\gdef\flushbookmark + {\doinsertsomebookmark{#1}{#2}{#3}{#4}{#5}{g}}% + \gdef\localbookmark##1% + {\doinsertsomebookmark{#1}{#2}{#3}{##1}{#5}{l}}} + +\def\doinsertsomebookmark#1#2#3#4#5#6% + {\global\utilitydonetrue + \global\let\localbookmark\gobbleoneargument + \global\let\flushbookmark\relax + \doifinstringelse{#1}\openbookmarklist + {\chardef\openbookmark\plusone} + {\chardef\openbookmark\zerocount}% + \iftracebookmarks(#6: #4)\quad(\the\openbookmark)\par\fi + \doinsertbookmark{#2}{#3}{#4}{#5}{\openbookmark}} + +% \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 ! + {\checkreferences % nodig ?? + \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-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-int.tex b/tex/context/base/core-int.tex deleted file mode 100644 index 79061958d..000000000 --- a/tex/context/base/core-int.tex +++ /dev/null @@ -1,2355 +0,0 @@ -%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} - -% 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 - -\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} - -%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} - -\def\@@bookmark {bm::} -\def\@@booklevel{bl::} -\def\@@bookcount{bc::} - -\definelist[\@@bookmark] - -\newtoks\postponedbookmarks - -\def\flushpostponedbookmark - {\the\postponedbookmarks - \global\postponedbookmarks\emptytoks} - -\def\simplebookmark#1% - {\doglobal\prependtoks - \writetolist[\@@bookmark]{}{#1}% - \to\postponedbookmarks} - -\def\complexbookmark[#1]#2% - {\doglobal\appendtoks\writetolist[#1]{}{#2}\to\postponedbookmarks} - -\definecomplexorsimple\bookmark - -\newif\iftracebookmarks \tracebookmarksfalse - -\let\tracebookmarks\tracebookmarkstrue - -\def\placebookmarks - {\dodoubleempty\doplacebookmarks} - -\def\doplacebookmarks[#1][#2]% - {\iflocation - \iffirstargument - \bgroup - \ifsecondargument - \doifelse{#2}\v!all - {\edef\openbookmarklist{#1}} - {\edef\openbookmarklist{#2}}% - \else - \let\openbookmarklist\empty - \fi - \global\let\bookmarklevellist\empty - \def\bookmarklevelcount{0}% - \doprocessbookmarks[#1]\dogetbookmarkelement - \dolistelement{}{}{}{}{}{}% needed to finish the first pass - \doprocessbookmarks[#1]\doputbookmarkelement - \flushbookmark - \egroup - \else - \expanded{\placebookmarks\@EA[\getvalue{\??ih\v!content\c!list}]}% - \fi - \fi} - -\def\doprocessbookmarks[#1]#2% - {\let\dolistelement#2\relax - \scratchcounter\zerocount - \def\docommand##1% - {\advance\scratchcounter \plusone - \getlistlevel[##1]\listlevel{\the\scratchcounter}% - \setxvalue{\@@bookcount\the\scratchcounter}{1}% - \setxvalue{\@@booklevel##1}{\listlevel}}% - \processcommalist[#1]\docommand - \setxvalue{\@@bookcount0}{1}% - \global\chardef\currentbookmarklevel\zerocount - \global\chardef\previousbookmarklevel\zerocount - \doutilities{listentries,#1,\@@bookmark}\jobname{#1}\relax\relax} - -\def\dodogetbookmarkelement#1#2#3#4#5#6% - {\doifelsenothing{#1} - {\global\chardef\currentbookmarklevel\zerocount} - {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% - \ifnum\currentbookmarklevel>\previousbookmarklevel - \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% - \else\ifnum\currentbookmarklevel<\previousbookmarklevel - \bgroup - \!!counta\previousbookmarklevel - \doloop - {\let\bookmarktag\empty - \!!countb\!!counta - \advance\!!countb \minusone - \dorecurse\!!countb - {\edef\bookmarktag - {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% - \edef\bookmarklevelcount - {\getvalue{\@@bookcount\the\!!counta}}% - \xdef\bookmarklevellist - {\bookmarklevellist/\bookmarktag:\bookmarklevelcount/}% - \advance\!!counta \minusone - \ifnum\!!counta=\currentbookmarklevel - \exitloop - \fi}% - \egroup - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax - \else - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax - \fi\fi - \global\utilitydonetrue - \global\chardef\previousbookmarklevel\currentbookmarklevel} - -\def\getbookmarklevelcount - {\@EA\def\@EA\docommand\@EA[\@EA##\@EA1\@EA/\bookmarktag:##2/##3]% - {\def\bookmarklevelcount{##2}}% - \@EA\@EA\@EA\docommand\@EA\@EA\@EA[\@EA\bookmarklevellist\@EA/\bookmarktag:0/]} - -\def\dodoputbookmarkelement#1#2#3#4#5#6% - {\doifelsenothing{#1} - {\global\chardef\currentbookmarklevel\zerocount} - {\global\chardef\currentbookmarklevel\getvalue{\@@booklevel#1}\relax}% - \ifnum\currentbookmarklevel>\previousbookmarklevel - \setxvalue{\@@bookcount\the\currentbookmarklevel}{1}% - \else\ifnum\currentbookmarklevel<\previousbookmarklevel - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\currentbookmarklevel\endcsname\relax - \else - \@EA\doglobal\@EA\increment\csname \@@bookcount\the\previousbookmarklevel\endcsname\relax - \fi\fi - \let\bookmarktag\empty - \!!countb\currentbookmarklevel - \dorecurse\!!countb - {\edef\bookmarktag - {\bookmarktag\getvalue{\@@bookcount\recurselevel}:}}% - \getbookmarklevelcount - \iftracebookmarks - \bgroup - \par - \bookmarktag\quad - \dorecurse\currentbookmarklevel{\quad}\unskip#1\quad - (\bookmarklevelcount)\quad - \egroup - \fi - \global\chardef\previousbookmarklevel\currentbookmarklevel - \global\utilitydonetrue - \insertsomebookmark{#1}{\the\currentbookmarklevel}{\bookmarklevelcount}{#4}{#6}} - -\def\dogetbookmarkelement#1#2#3#4#5#6% - {\doifnot{#1}\@@bookmark - {\dodogetbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} - -\def\doputbookmarkelement#1#2#3#4#5#6% - {\doifelse{#1}\@@bookmark - {\localbookmark{#4}} - {\flushbookmark - \dodoputbookmarkelement{#1}{#2}{#3}{#4}{#5}{#6}}} - -\let\flushbookmark\relax -\let\localbookmark\gobbleoneargument - -\def\insertsomebookmark#1#2#3#4#5% - {\gdef\flushbookmark - {\doinsertsomebookmark{#1}{#2}{#3}{#4}{#5}{g}}% - \gdef\localbookmark##1% - {\doinsertsomebookmark{#1}{#2}{#3}{##1}{#5}{l}}} - -\def\doinsertsomebookmark#1#2#3#4#5#6% - {\global\utilitydonetrue - \global\let\localbookmark\gobbleoneargument - \global\let\flushbookmark\relax - \doifinstringelse{#1}\openbookmarklist - {\chardef\openbookmark\plusone} - {\chardef\openbookmark\zerocount}% - \iftracebookmarks(#6: #4)\quad(\the\openbookmark)\par\fi - \doinsertbookmark{#2}{#3}{#4}{#5}{\openbookmark}} - -% \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 ! - {\checkreferences % nodig ?? - \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\box\voidb@x}% - {\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-ltb.tex b/tex/context/base/core-ltb.tex deleted file mode 100644 index 3ebd16379..000000000 --- a/tex/context/base/core-ltb.tex +++ /dev/null @@ -1,856 +0,0 @@ -%D \module -%D [ file=core-ltb, -%D version=2002.10.31, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Line 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. - -% testfile: tfmetrics.tex - -% todo: als nx>1, dan in geval van rek tussenruimte berekenen en optellen -% bij breedte, dus: nx nog niet gebruiken in combinatie met rek ! ! ! ! ! - -% This module is experimental, undocumented, and currently only set up -% eTeX. It provides a mechanism for typesetting very large tables, -% spanning many pages horizontally and vertically, with repeated -% header lines and (entry) columns, tab tracking, color, etc. In does -% two passes over a table, which is why the table goes into a -% buffer or file. As said, tables can be real huge. - -% \BH \BC .. \EC \BC .. \EC \EH % append -% \BR \BC .. \EC \BC .. \EC \ER -% -% or -% -% \NC .. \NC .. \NC \NR (todo: optional last \NC) - -% alternative: -% -% (1) direct run, save content in macro, but only if needed -% -% todo -% -% (2) buffered table content -% -% \startbuffer -% \startlinetablehead -% \stoplinetablehead -% \startlinetablebody -% \stoplinetablebody -% \stopbuffer -% -% \processlinetablebuffer[buffer] -% -% in buffer : head and body -% -% (3) unbuffered run, multipass -% -% - run with starting width zero / prev run -% - clip on prev run -% - flush real widths - -\writestatus{loading}{Context Core Macros / Line Tables} - -\unprotect - -\chardef\linetablesplitstate\zerocount -\chardef\linetableheadstate \zerocount - -\edef\??ler{\??le:r:} -\edef\??lec{\??le:c:} -\edef\??lew{\??le:w:} -\edef\??leh{\??le:h:} -\edef\??led{\??le:d:} - -\newif\iflinetablepreroll -\newif\ifinlinetable - -\newcount\linetablecolumn -\newcount\linetablesubcol -\newdimen\linetablewidth -\newdimen\linetableheight -\newbox \linetablecell - -\let\noflinetablecolumns\!!zerocount -\let\noflinetablerows \!!zerocount -\let\noflinetablelines \!!zerocount -\let\noflinetableparts \!!zerocount -\let\linetablepart \!!plusone -\let\linetablestep \!!plusone -\let\linetableline \!!zerocount -\let\linetablerow \!!zerocount -\let\linetablerows \!!zerocount - -\initializetablebox \zerocount % holds repeater - -\chardef\linetablehmode \zerocount -\chardef\linetablepage \zerocount -\chardef\linetablerepeat\zerocount - -\def\setuplinetable - {\dotripleempty\dosetuplinetable} - -\def\dosetuplinetable[#1][#2][#3]% - {\ifthirdargument - \getparameters[\??le:#1:#2][#3]% - \else\ifsecondargument - \getparameters[\??lec#1][#2]% - \else - \getparameters[\??le][#1]% - \fi\fi} - -\setuplinetable - [\c!n=\!!maxcard, - \c!lines=\!!maxcard, - \c!nx=\plusone, - \c!nleft=0, - \c!repeat=\v!yes, % when \c!nleft>0, repeat on both pages - \c!before=, - \c!after=, - \c!inbetween=\page, - \c!distance=\zeropoint, - \c!stretch=\v!no, - \c!align=\c!right, - \c!leftoffset=.25ex, - \c!rightoffset=\linetableparameter\c!leftoffset, - \c!maxwidth=\zeropoint, - \c!width=5em, - \c!height=\v!fit, % \v!line = faster - \c!background=, - \c!backgroundcolor=] - -\def\linetableparameter#1% - {\csname\??le#1\endcsname} - -\def\doifelselinetablecparameter#1% - {\ifcsname\??lec\number\linetablecolumn#1\endcsname - \expandafter\firstoftwoarguments - \else - \expandafter\secondoftwoarguments - \fi} - -\def\linetablecparameter#1% - {\csname - \ifcsname\??lec\number\linetablecolumn#1\endcsname - \??lec\number\linetablecolumn - \else - \??le - \fi - #1\endcsname} - -\def\linetablerparameter#1% faster, leaner and meaner - {\csname - \ifnum\linetablerow=\zerocount % geen ifcase - \ifcsname\??ler\v!header#1\endcsname - \??ler\v!header#1% - \else\ifcsname\??ler0#1\endcsname - \??ler0#1% - \else - \s!empty - \fi\fi - \else - \ifcsname\??ler\number\linetablerow#1\endcsname - \??ler\number\linetablerow#1% - \else\ifcsname\??ler\v!oddeven\linetablerow#1\endcsname - \??ler\v!oddeven\linetablerow#1% - \else - \s!empty - \fi\fi - \fi - \endcsname} - -\def\setnoftableslines - {\doifelse{\linetableparameter\c!lines}\v!fit - {% whitespace already added by vertical strut - \ifdim\pagegoal<\maxdimen - \scratchdimen\pagegoal - \advance\scratchdimen -\pagetotal - \else - \scratchdimen\textheight - \fi - \getrawnoflines\scratchdimen - \xdef\noflinetablelines{\the\noflines} -\iflinetablepreroll \else \ifnum\noflinetablelines<\plustwo - \page \setnoftableslines -\fi \fi -} - {\xdef\noflinetablelines{\linetableparameter\c!lines}}} - -\def\startlinetablecell - {\dosingleempty\dostartlinetablecell} - -\def\dostartlinetablecell[#1]% - {\global\setbox\linetablecell\hbox\bgroup - \iffirstargument - \getparameters[\??lec\number\linetablecolumn][#1]% - \fi - \xdef\linetablestep{\linetablecparameter\c!nx}% - \ifcase\linetablestep\or - \scratchdimen\linetablecparameter\c!width - \scratchskip \linetablecparameter\c!distance - \else - \scratchdimen \zeropoint - \scratchskip \zeropoint - \scratchcounter\linetablecolumn - \dorecurse\linetablestep - {\advance\scratchdimen\linetablecparameter\c!width - %\advance\scratchskip \linetablecparameter\c!distance - \global\advance \linetablecolumn\plusone - \advance\scratchskip \linetablecparameter\c!distance - }% - \global\linetablecolumn\scratchcounter - \fi - \chardef\linetablemode - \iflinetablepreroll - \ifdim\scratchdimen>\zeropoint \zerocount \else \plustwo \fi - \else - \zerocount - \fi - \ifcase\linetablemode - \ifcase\linetablehmode - % nothing - \or - % fit, keep it simple - \or - \chardef\linetablemode\plusone % line - \else - % some already calculated height - \fi - \fi - \setbox\scratchbox\hbox - \bgroup - \dontcomplain - \hskip\linetablecparameter\c!leftoffset\relax - % 0 = width, unknown height - % 1 = width, fixed height - % 2 = no width, auto hsize - \ifnum\linetablemode<\plustwo - \advance\scratchdimen-\linetablecparameter\c!leftoffset - \advance\scratchdimen-\linetablecparameter\c!rightoffset - \fi - \ifcase\linetablemode - \dosetraggedcommand{\linetablecparameter\c!align}% - \vtop \ifdim\linetableheight>\zeropoint to\linetableheight \fi \bgroup - \hsize\scratchdimen - \raggedcommand - \else - \setalignmentswitch{\linetablecparameter\c!align}% - \hbox \ifcase\linetablemode \or to\scratchdimen \fi \bgroup - \ifcase\alignmentswitch\hss\or\hss\fi - \fi - \dostartattributes{\??lec\number\linetablecolumn}\c!style\c!color\empty - \begstrut \ignorespaces} - -% \def\stoplinetablecell -% {\unskip \endstrut -% \dostopattributes -% \ifcase\linetablemode -% \endgraf -% \else -% \ifcase\alignmentswitch\else\hss\fi -% \fi -% \egroup -% \hskip\linetablecparameter\c!rightoffset -% \egroup -% \iflinetablepreroll -% \box\scratchbox -% \else -% \doif{\linetablecparameter\c!background}\v!color -% {\backgroundline[\linetablecparameter\c!backgroundcolor]}% -% {\box\scratchbox}% -% \fi -% \egroup} - -\newconditional\linetableautoheight \settrue\linetableautoheight - -\def\stoplinetablecell - {\unskip \endstrut - \dostopattributes - \ifcase\linetablemode - \endgraf - \else - \ifcase\alignmentswitch\else\hss\fi - \fi - \egroup - \hskip\linetablecparameter\c!rightoffset - \egroup - \iflinetablepreroll - \box\scratchbox - \else - \doifelse{\linetablecparameter\c!background}\v!color - {\ifconditional\linetableautoheight - \hbox{\blackrule - [ \c!color=\linetablecparameter\c!backgroundcolor, - \c!height=\linetablerparameter{x\c!height}, - \c!depth=\linetablerparameter{x\c!depth}, - \c!width=\wd\scratchbox]% - \hskip-\wd\scratchbox\box\scratchbox}% - \else - \backgroundline[\linetablecparameter\c!backgroundcolor]{\box\scratchbox}% - \fi}% - {\box\scratchbox}% - \fi - \egroup} - -% \def\stoplinetablecell -% {\unskip \endstrut -% \dostopattributes -% \ifcase\linetablemode -% \endgraf -% \else -% \ifcase\alignmentswitch\else\hss\fi -% \fi -% \egroup -% \hskip\linetablecparameter\c!rightoffset -% \egroup -% \iflinetablepreroll -% \box\scratchbox -% \else -% \doifelse{\linetablecparameter\c!background}\v!color -% {\ifconditional\linetableautoheight -% % \hbox{\blackrule -% % [ \c!color=\linetablecparameter\c!backgroundcolor, -% % \c!height=\linetablerparameter{x\c!height}, -% % \c!depth=\linetablerparameter{x\c!depth}, -% % \c!width=\wd\scratchbox]% -% % \hskip-\wd\scratchbox\box\scratchbox}% -% \dp\scratchbox\linetablerparameter{x\c!depth}% -% \ht\scratchbox\linetablerparameter{x\c!height}% -% \framed -% [\c!offset=\v!overlay, -% \c!frameoffset=.5\linewidth, -% \c!leftframe=\v!off,\c!rightframe=\v!off, -% \c!background=\v!color, -% \c!backgroundcolor=\linetablecparameter\c!backgroundcolor% -% ]{\box\scratchbox}% -% \else -% \backgroundline[\linetablecparameter\c!backgroundcolor]{\box\scratchbox}% -% \fi}% -% {\box\scratchbox}% -% \fi -% \egroup} - -\def\savelinetablepart - {\global\setbox\tablebox\linetablepart - \ifnum\linetablepart=\zerocount - \box\scratchbox % just storing - \else - \vbox - {\ifvoid\tablebox\linetablepart\else\unvbox\tablebox\linetablepart\fi - \doif{\linetablerparameter\c!background}\v!color - {\backgroundline[\linetablerparameter\c!backgroundcolor]}% - {\box\scratchbox}% is also arg to \backgroundline - \endgraf - \linetablerparameter\c!after}% - \fi} - -\def\flushlinetableparts - {\doglobal\increment\linetableline - \ifnum\linetableline<\noflinetablelines - % keep collecting - \else - \iflinetablepreroll - % forget about them - \else - \dorecurse\noflinetableparts - {\let\linetablepart\recurselevel - \dp\tablebox\linetablepart\strutdepth - % noindent en endgraf needed else whitespace mess-up! - \whitespace % here not after verticalstrut - \ifdim\topskipgap=\zeropoint\else - \verticalstrut\nobreak\kern-\struttotal\kern-\parskip\nobreak\nointerlineskip % fix topskip - \fi - \noindent\strut\hbox to \hsize{\box\tablebox\linetablepart\hss}\endgraf - \ifnum\linetablepart<\noflinetableparts\relax - \linetableparameter\c!inbetween - \fi}% - \ifnum\linetablerows<\noflinetablerows\relax - \linetableparameter\c!inbetween - \else - % after, later - \fi - \chardef\linetableheadstate\plusthree - \global\setbox\tablebox\zerocount\emptybox % here - \fi - % reset \linetablerow will be an option, currently - % starts at zero after split - \globallet\linetablerow\!!zerocount - \globallet\linetableline\!!zerocount - \global\chardef\linetablepage\zerocount - \global\linetablewidth\zeropoint - \setnoftableslines - \fi} - -\def\startlinetablepart - {\global\linetablesubcol\zerocount - \setbox\scratchbox\hbox\bgroup - \doconvertfont{\linetablerparameter\c!style}% - \startcolor[\linetablerparameter\c!color]% - \ignorespaces} - -\def\stoplinetablepart - {\ifnum\linetablepart>\zerocount - \unskip \unskip % remove last intercolumn skip (distance+fill) - \fi - \stopcolor - \egroup - \iflinetablepreroll \else - \ifcase\linetablepart - % we're collecting the repeater - \else - \scratchdimen\hsize \advance\scratchdimen-\wd\scratchbox\relax - \ifdim\scratchdimen>\linetableparameter\c!stretch\else - \setbox\scratchbox\hbox to \hsize{\unhbox\scratchbox}% - \fi - \fi - \fi} - -\def\checklinetablepart - {\global\advance\linetablewidth\wd\linetablecell - \global\advance\linetablecolumn\linetablestep - \global\advance\linetablesubcol\linetablestep - \relax - %\message{\the\linetablecolumn,\the\linetablesubcol}\wait - % from now on the column counter is already incremented - \ifcase\linetablesplitstate - \iflinetablepreroll \else - \box\linetablecell - % the columncounter is one ahead ! -% \hskip\linetablecparameter\c!afstand - \hskip\scratchskip - \fi - %%% - \donefalse - \ifcase\linetablerepeat\else - % van te voren berekenen - \scratchcounter\linetablecolumn\advance\scratchcounter-\plustwo - \ifnum\linetablerepeat=\scratchcounter - \donetrue % collecting repeater - \fi - \fi - %%%% - \ifdone - % collecting repeater - \else - \ifnum\linetablecolumn>\getvalue{\??le::\linetablepart}\relax - \donetrue - \fi - \fi - \ifdone - \stoplinetablepart - \iflinetablepreroll \else - \savelinetablepart - \fi - \ifcase\linetablepage \or - \global\chardef\linetablepage \plustwo - \else - \global\chardef\linetablepage \plusone - \fi - \doglobal\increment\linetablepart - \global\linetablewidth\wd\tablebox\zerocount - \startlinetablepart - \fi - \else - \donefalse - \!!doneafalse - \ifcase\linetablerepeat\else - % van te voren berekenen - \scratchcounter\linetablecolumn \advance\scratchcounter-\plustwo - \ifnum\linetablerepeat=\scratchcounter - \donetrue % collecting repeater - \fi - \fi - \ifdone - \!!doneatrue - % collecting repeater - \else\ifdim\linetablewidth>\hsize - \donetrue - \else -% \global\advance\linetablewidth\linetablecparameter\c!afstand\relax - \global\advance\linetablewidth\scratchskip - \ifdim\linetablewidth>\hsize % ? - \donetrue - \fi - \fi\fi - \ifdone - \stoplinetablepart - \savelinetablepart - \ifcase\linetablepage \or - \global\chardef\linetablepage \plustwo - \else - \global\chardef\linetablepage \plusone - \fi - \doglobal\increment\linetablepart - \ifnum\linetablepart>\noflinetableparts - \globallet\noflinetableparts\linetablepart - \initializetablebox\linetablepart - \fi - \global\linetablewidth\wd\linetablecell - \startlinetablepart - \if!!doneb \else \ifcase\linetablerepeat \else - % check for left/right page - \ifcase\linetablepage\donetrue\or\donetrue\or\donefalse\fi\ifdone - % insert repeater - \global\advance\linetablewidth\wd\tablebox\zerocount - \iflinetablepreroll\kern\wd\else\unhcopy\fi\tablebox\zerocount - \fi - \fi \fi - \fi - \iflinetablepreroll \else - \box\linetablecell - % the columncounter is one ahead ! -% \hskip\linetablecparameter\c!afstand -% \hskip\scratchskip -\dorecurse\linetablestep{\strut\hfil}% - \hskip\scratchskip - \fi - \fi} - -% \linetableparameter\c!var -> \@@levar (when no classes) - -\def\startlinetablerun % to do: quit when nested - {\bgroup - \inlinetabletrue - % autowidth - \doif{\linetableparameter\c!maxwidth}\v!fit - {\setuplinetable[\c!maxwidth=\zeropoint]}% - \processaction - [\linetableparameter\c!stretch] - [ \v!no=>{\setuplinetable[\c!stretch=\maxdimen]},% no stretch - \v!yes=>{\setuplinetable[\c!stretch=\zeropoint]}]% max stretch - \chardef\linetablerepeat\linetableparameter\c!nleft - \chardef\linetablesplitstate % = - \ifdim\linetableparameter\c!maxwidth>\zeropoint - \zerocount \else \plusone - \fi - % optional prevdepth correction - \iflinetablepreroll - \globallet\noflinetablerows\!!zerocount - \else - \linetableparameter\c!before - \fi - \globallet\linetablerows\!!zerocount - \globallet\noflinetablecolumns\!!zerocount - \globallet\noflinetableparts\!!zerocount - \!!counta\zerocount - \def\docommand##1% - {\doglobal\increment\noflinetableparts - \advance\!!counta##1% - \setxvalue{\??le::\noflinetableparts}{\the\!!counta}}% - \processcommacommand[\linetableparameter\c!n]\docommand - \initializetableboxes\noflinetableparts - \ifcase\linetablerepeat - \globallet\linetablepart\!!plusone - \else - \globallet\linetablepart\!!zerocount % repeater - \fi - \globallet\linetablestep\!!plusone - \globallet\linetableline\!!zerocount - \globallet\linetablerow \!!zerocount - \global\linetablecolumn \zerocount - \global\linetablesubcol \zerocount - \global\linetablewidth \zeropoint -\iflinetablepreroll \else \ifdim\pagetotal>\zeropoint - \verticalstrut\kern-\struttotal -\fi \fi - \setnoftableslines - \checklinetablepage - \let\BR\linetableBR - \let\ER\linetableER - \let\BH\linetableBR - \let\EH\linetableER - \let\BC\linetableBC - \let\EC\linetableEC - \let\NC\linetableNC - \let\NR\linetableNR - \flushlinetablehead} - -\def\stoplinetablerun - {\globallet\linetableline\!!maxcard - \chardef\linetableheadstate\zerocount % blocked - \flushlinetableparts - \iflinetablepreroll \else - \linetableparameter\c!after - \fi - \globallet\linetablepart \!!zerocount - \globallet\noflinetableparts\!!zerocount - \egroup} - -% \def\checklinecolumnwidth -% {\ifundefined{\??lew\number\linetablecolumn}% -% \donetrue -% \else\ifdim\getvalue{\??lew\number\linetablecolumn}<\wd\linetablecell -% \donetrue -% \else -% \donefalse -% \fi\fi -% \ifdone -% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% -% \fi} -% -% \def\checklinecolumnwidth -% {\ifcsname\??lew\number\linetablecolumn\endcsname -% \ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell -% \donetrue -% \else -% \donefalse -% \fi -% \else -% \donetrue -% \fi -% \ifdone -% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% -% \fi} - -% \def\checklinecolumnwidth -% {\expandafter\xdef\csname\??lew\number\linetablecolumn\endcsname -% {\expandafter\ifx\csname\??lew\number\linetablecolumn\endcsname\relax -% \the\wd\linetablecell -% \else\ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell -% \the\wd\linetablecell -% \else -% \csname\??lew\number\linetablecolumn\endcsname -% \fi\fi}} - -\def\checklinecolumndimension#1#2#3% - {\expandafter\xdef\csname#1\number#3\endcsname - {\expandafter\ifx\csname#1\number#3\endcsname\relax - \the#2\linetablecell - \else\ifdim\csname#1\number#3\endcsname<#2\linetablecell - \the#2\linetablecell - \else - \csname#1\number#3\endcsname - \fi\fi}} - -\def\checklinecolumnwidth {\checklinecolumndimension\??lew\wd\linetablecolumn} -\def\checklinecolumnheight{\checklinecolumndimension\??leh\ht\linetablerow} -\def\checklinecolumndepth {\checklinecolumndimension\??led\dp\linetablerow} - -\def\linetableBR - {\dosingleempty\dolinetableBR} - -\def\dolinetableBR[#1]% #1 not yet implemented - {\ifnum\linetableheadstate=1\else - \doglobal\increment\linetablerow - \doglobal\increment\linetablerows - \fi - \global\linetablecolumn\plusone - \global\linetablesubcol\plusone -% \linetableheight\linetablerparameter\c!height -% -% \ifx\linetableheight\empty -% % nothing -% \else\ifx\linetableheight\v!fit -% % keep it simple -% \else\ifx\linetableheight\v!line -% \chardef\linetablemode\plusone -% \else -% \!!heighta\linetableheight -% \advance\!!heighta-\strutdepth -% \fi\fi\fi -% - \linetableheight\zeropoint - \edef\!!stringa{\linetablerparameter\c!height}% - \ifx\!!stringa\empty - \chardef\linetablehmode\zerocount - \else\ifx\!!stringa\v!fit - \chardef\linetablehmode\plusone - \else\ifx\!!stringa\v!line - \chardef\linetablehmode\plustwo - \else - \linetableheight\!!stringa - \advance\linetableheight-\strutdepth - \fi\fi\fi -% - \startlinetablepart} - -\def\linetableBC - {\startlinetablecell} - -\def\linetableEC - {\stoplinetablecell - \iflinetablepreroll - \checklinecolumnwidth - \checklinecolumnheight - \checklinecolumndepth - \fi - \checklinetablepart} - -\def\linetableER - {% \stoplinetablecell - % no \box\linetablecell, i.e. dummy columnn, last \NC \NR - \stoplinetablepart - \savelinetablepart - \advance\linetablecolumn \minusone - \ifnum\linetablecolumn>\noflinetablecolumns - \xdef\noflinetablecolumns{\number\linetablecolumn}% - \fi - \flushlinetableparts - \global\linetablecolumn\zerocount - \global\linetablewidth \zeropoint - \ifcase\linetablerepeat - \globallet\linetablepart\!!plusone - \else - \globallet\linetablepart\!!zerocount % repeater - \fi - \checklinetablepage - \flushlinetablehead} - -\def\checklinetablepage - {\global\chardef\linetablepage\zerocount - \ifcase\linetablerepeat \else \ifcase\linetablepage - \doif{\linetableparameter\c!repeat}\v!no - {\global\chardef\linetablepage\doifoddpageelse\plusone\plustwo}% - \fi \fi} - -\def\flushlinetablehead - {\ifcase\linetableheadstate - % 0 blocked - \or - % 1 doing head - \or - % 2 head done - \or - % 3 trigger flush - \chardef\linetableheadstate\plusone - \the\@@linetablehead\relax - \chardef\linetableheadstate\plustwo - \fi} - -\def\linetableNC % first time special treatment - {\relax - \ifcase\linetablecolumn - \linetableBR - \else - \linetableEC - \fi - \linetableBC} % beware, this will result in BR BC EC BC NR - -\def\linetableNR - {\stoplinetablecell % dummy - \linetableER} - -\def\startlinetable - {\startlinetablerun} - -\def\stoplinetable - {\stoplinetablerun} - -\def\startlinetableanalysis - {\bgroup - \linetableprerolltrue - \trialtypesettingtrue - \startlinetablerun} - -\def\stoplinetableanalysis - {\stoplinetablerun - \egroup - \globallet\noflinetablerows\linetablerows - \dorecurse\noflinetablerows % global, from last run {\linetableparameter\c!n} - {%\writestatus{linetable}{\recurselevel->\getvalue{\??lew\recurselevel}}% - \setevalue{\??ler\recurselevel x\c!height}{\getvalue{\??leh\recurselevel}}% - \setevalue{\??ler\recurselevel x\c!depth }{\getvalue{\??led\recurselevel}}% - \letgvalue{\??leh\recurselevel}\!!zeropoint - \letgvalue{\??led\recurselevel}\!!zeropoint} - \dorecurse\noflinetablecolumns % global, from last run {\linetableparameter\c!n} - {%\writestatus{linetable}{\recurselevel->\getvalue{\??lew\recurselevel}}% - \setevalue{\??lec\recurselevel\c!width}{\getvalue{\??lew\recurselevel}}% - \letgvalue{\??lew\recurselevel}\!!zeropoint}} % init next table - -% todo: store in box instead of macro - -\newtoks \@@linetablehead - -\long\def\startlinetablehead#1\stoplinetablehead - {\ifinlinetable - \@@linetablehead\emptytoks - \fi - \chardef\linetableheadstate3 % full - \@@linetablehead{#1}% - \ifinlinetable - \flushlinetablehead - \fi} - -\def\linetableBH - {\ifx\EC\relax - % signal, grabbing lines - \else - \@@linetablehead\emptytoks - \fi - \pushmacro\BC - \pushmacro\EC - \def\BC##1\EC{\appendtoks##1\to\@@linetablehead}% - \let\EC\relax} % signal - -\def\linetableEH - {\popmacro\EC - \popmacro\BC - \@EA\startlinetablehead\the\@@linetablehead\stoplinetablehead} - -\let\startlinetablebody\donothing -\let\stoplinetablebody \donothing - -\def\processlinetablebuffer - {\dosingleempty\doprocesslinetablebuffer} - -\def\doprocesslinetablebuffer[#1]% - {\bgroup - \let\startlinetable\donothing - \let\stoplinetable \donothing - \startlinetableanalysis\getbuffer[#1]\stoplinetableanalysis - \startlinetablerun \getbuffer[#1]\stoplinetablerun - \egroup} - -\def\processlinetablefile#1% - {\bgroup - \let\startlinetable\donothing - \let\stoplinetable \donothing - \startlinetableanalysis\readfile{#1}\donothing\donothing\stoplinetableanalysis - \startlinetablerun \readfile{#1}\donothing\donothing\stoplinetablerun - \egroup} - -\protect \endinput - -\doifnotmode{demo}{\endinput} - -\setuplinetable[n=6,m={2,2,2},lines=25] % m ? - -\setuplinetable[c][1] [width=2cm,background=color,backgroundcolor=red] -\setuplinetable[c][4] [width=3cm,background=color,backgroundcolor=yellow] -\setuplinetable[c][6] [width=3cm,background=color,backgroundcolor=magenta] -\setuplinetable[r][odd] [background=color,backgroundcolor=gray] -\setuplinetable[r][even][background=color,backgroundcolor=green] - -\starttext - -\showframe \showstruts - -\setupcolors[state=start] - -\setuppagenumbering[alternative=doublesided]\page[left] - -\startlinetable -\NC aaa\crlf aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR -\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR} -\stoplinetable - -\startlinetable -\NC[style=slanted,color=green,background=color,backgroundcolor=darkred,nx=2,uitlijnen=middle] xxx - \NC yy \NC ddddd \NC eeee \NC ff \NC \NR -\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR} -\stoplinetable - -% \startbuffer[lt] -% \NC aaa\crlf aaa \NC bb \NC c \NC ddddd \NC ee \NC ff \NC \NR -% \NC aaa\crlf aaa \NC b \NC cc \NC ddd \NC eeee \NC f \NC \NR -% \stopbuffer -% -% \processlinetablebuffer[lt] - -\stoptext 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.mkii b/tex/context/base/core-mis.mkii new file mode 100644 index 000000000..e860a537a --- /dev/null +++ b/tex/context/base/core-mis.mkii @@ -0,0 +1,2676 @@ +%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]% + {\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 [] + +% 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 +\newcounter\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 + \doglobal\increment\subsentencelevel + \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]% + \doglobal\decrement\subsentencelevel + \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 test 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\delimitedtextparameter#1% will be sped up + {\executeifdefined{\??ci\currentdelimitedtext:\csname\??ci\currentdelimitedtext\c!level\endcsname#1}% + {\executeifdefined{\??ci\currentdelimitedtext#1}% + {\executeifdefined{\??ci#1}\empty}}} + +\def\definedelimitedtext + {\dodoubleempty\dodefinedelimitedtext} + +\def\dodefinedelimitedtext[#1][#2]% + {\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\delimitedtextparameter\c!level\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}% + \doglobal\incrementvalue{\??ci\currentdelimitedtext\c!level}} + +\def\popdelimitedtext + {\doglobal\decrementvalue{\??ci\currentdelimitedtext\c!level}% + \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\!!tenthousand + \hskip\zeropoint % == \prewordbreak + \fi + \strut % new, needed below + \delimitedtextparameter#1% unhbox\scratchbox +% \penalty\!!tenthousand % 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\!!tenthousand + \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 + \hskip\hspaceamount\currentlanguage{interquotation}% + \else\ifdim\lastskip=\delimitedtextsignal + \unskip + \hskip\hspaceamount\currentlanguage{interquotation}% + \else + #2% + \fi\fi + \ifhmode % else funny pagebeaks + \penalty\!!tenthousand + \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 + +% Dit wordt: +% +% \doorverwijzen[naam][instellingen] enz. +% +% waarbij bijvoorbeeld publicatie is. Dit levert: +% +% \start +% \stop +% +% \beginvan +% \eindvan +% +% \publicatie +% +% \volledigelijstmetpublicaties +% +% eigenlijk kan ook door... zo worden uitgebreid! + +% 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={]}] + +% 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-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 test 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-mis.tex b/tex/context/base/core-mis.tex deleted file mode 100644 index de1da7597..000000000 --- a/tex/context/base/core-mis.tex +++ /dev/null @@ -1,2733 +0,0 @@ -%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 - -% 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. -% %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{\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\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]% - {\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 [] - -% 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 -\newcounter\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 - \doglobal\increment\subsentencelevel - \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]% - \doglobal\decrement\subsentencelevel - \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 test 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\delimitedtextparameter#1% will be sped up - {\executeifdefined{\??ci\currentdelimitedtext:\csname\??ci\currentdelimitedtext\c!level\endcsname#1}% - {\executeifdefined{\??ci\currentdelimitedtext#1}% - {\executeifdefined{\??ci#1}\empty}}} - -\def\definedelimitedtext - {\dodoubleempty\dodefinedelimitedtext} - -\def\dodefinedelimitedtext[#1][#2]% - {\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\delimitedtextparameter\c!level\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}% - \doglobal\incrementvalue{\??ci\currentdelimitedtext\c!level}} - -\def\popdelimitedtext - {\doglobal\decrementvalue{\??ci\currentdelimitedtext\c!level}% - \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\!!tenthousand - \hskip\zeropoint % == \prewordbreak - \fi - \strut % new, needed below - \delimitedtextparameter#1% unhbox\scratchbox -% \penalty\!!tenthousand % 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\!!tenthousand - \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 - \hskip\hspaceamount\currentlanguage{interquotation}% - \else\ifdim\lastskip=\delimitedtextsignal - \unskip - \hskip\hspaceamount\currentlanguage{interquotation}% - \else - #2% - \fi\fi - \ifhmode % else funny pagebeaks - \penalty\!!tenthousand - \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 - -% Dit wordt: -% -% \doorverwijzen[naam][instellingen] enz. -% -% waarbij bijvoorbeeld publicatie is. Dit levert: -% -% \start -% \stop -% -% \beginvan -% \eindvan -% -% \publicatie -% -% \volledigelijstmetpublicaties -% -% eigenlijk kan ook door... zo worden uitgebreid! - -% 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={]}] - -% 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 - -\startmessages dutch library: systems - 41: externe file -- in groep -- bestaat niet -\stopmessages - -\startmessages english library: systems - 41: external file -- in group -- does not exist -\stopmessages - -\startmessages german library: systems - 41: Externe Datei -- in Gruppe -- existiert nicht -\stopmessages - -\startmessages czech library: systems - 41: externi soubor -- ve skupine -- neexistuje -\stopmessages - -\startmessages italian library: systems - 41: il file esterno -- del gruppo -- non esiste -\stopmessages - -\startmessages norwegian library: systems - 41: ekstern fil -- i gruppe -- eksisterer ikke -\stopmessages - -\startmessages romanian library: systems - 41: fisierul extern -- din grupul -- nu exista -\stopmessages - -\startmessages french library: systems - 41: le fichier externe -- du groupe -- n'existe pas -\stopmessages - -\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: - -\newevery \everyinsidefloat \relax - -\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 - \calculatecos\@@rorotation\edef\cos{\calculatedcos\@@rorotation}% - \calculatesin\@@rorotation\edef\sin{\calculatedsin\@@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.mkii b/tex/context/base/core-nav.mkii new file mode 100644 index 000000000..f4594ab3b --- /dev/null +++ b/tex/context/base/core-nav.mkii @@ -0,0 +1,379 @@ +%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} + +%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-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-nav.tex b/tex/context/base/core-nav.tex deleted file mode 100644 index 045a05123..000000000 --- a/tex/context/base/core-nav.tex +++ /dev/null @@ -1,379 +0,0 @@ -%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} - -%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-new.tex b/tex/context/base/core-new.tex deleted file mode 100644 index e96039d10..000000000 --- a/tex/context/base/core-new.tex +++ /dev/null @@ -1,304 +0,0 @@ -%D \module -%D [ file=core-nav, -%D version=1995.01.01, -%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 / New Ones} - -\unprotect - -\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[% - {\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 [..] - -\def\dosetupsA #1{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % {..} -\def\dosetupsB[#1]{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % [..] -\def\dosetupsC[#1]{\cleanuplabel{#1}\dosetups\cleanlabel} % [..] - -% \def\dosetups#1% the grid option will be extended to other main modes -% {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} -% {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument -% -% \def\setupwithargument#1% the grid option will be extended to other main modes -% {\executeifdefined{\??su:#1}\gobbleoneargument} - -% better: - -% \def\dosetups#1% the grid option will be extended to other main modes -% {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} -% {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument -% -% \def\setupwithargument#1% the grid option will be extended to other main modes -% {\executeifdefined{\??su:#1}\gobbleoneargument} - -% faster: - -\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 - -% somehow fails ... -% -% \letvalue{\??su:..}\gobbleoneargument -% -% \def\dosetups#1% the grid option will be extended to other main modes -% {\csname \??su -% \ifcsname\??su\ifgridsnapping\v!grid\fi:#1\endcsname\v!grid:#1\else -% \ifcsname\??su :#1\endcsname :#1\else -% :..\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..\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\chardef\setupseolmode#1\doifnextcharelse[{\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% watch out: not \grabuntil -% {\dograbuntil#1{\endgroup\dodoglobal\long\setvalue{\??su#2:#3}}} % \doglobal -% -% better: - -% \long\def\dodostartsetups#1#2#3% watch out: not \grabuntil -% {\cleanuplabel{\??su#2:#3}\dograbuntil#1{\endgroup\dodoglobal\long\setvalue\cleanlabel}} % \doglobal - -% \long\def\dodostartsetups#1#2#3% -% {\cleanuplabel{\??su#2:#3}% -% \long\def\dododostartsetups##1#1{\endgroup\dodoglobal\long\setvalue\cleanlabel####1{##1}}\dododostartsetups} - -\long\def\dodostartsetups#1#2#3% - {\cleanuplabel{\??su#2:#3}% - \long\def\dododostartsetups##1#1% - {\endgroup - \dodoglobal % bah - \long\expandafter\setvalue\expandafter\cleanlabel\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 - {\ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}% - \dodoglobal\letbeundefined{\??su:#1}% - \else - \dodoglobal\letbeundefined{\??su\ifgridsnapping\v!grid\fi:#1}% - \fi} - -% or -% -% \def\resetsetups[#1]% -% {\letbeundefined -% {\??su:% -% \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}}} - -\def\defineshortcut - {\dotripleargument\dodefineshortcut} - -\def\dodefineshortcut[#1][#2][#3]% - {\ifthirdargument - \ConvertConstantAfter\doifelse{#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} % - \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 \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 test -%D test test -%D test test -%D test test -%D zus<>zo zus<:>zo zus<::>zo -%D test test dat (ziezo) -%D test test dat (:ziezo) -%D test test dat (ziezo:) -%D test test dat (zi:ezo:) -%D well, 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 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\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 - -\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-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-ntb.tex b/tex/context/base/core-ntb.tex deleted file mode 100644 index 5bfba05ad..000000000 --- a/tex/context/base/core-ntb.tex +++ /dev/null @@ -1,1573 +0,0 @@ -%D \module -%D [ file=core-ntb, -%D version=2000.04.18, -%D title=\CONTEXT\ Core 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 Core 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 However, the next alternative also takes care of preceding -%D and following white space. - -% \def\bTBLCELL % why not \doinhibitblank -% {\inhibitblank\doconvertfont\tbltblstyle\empty\everypar{\delayedbegstrut}} - -% \def\eTBLCELL -% {\ifhmode -% \delayedendstrut -% \par % added 13/4/2006 -% \else -% \par -% \ifdim\prevdepth<\zeropoint % =-1000pt ? -% \vskip-\strutdp -% \else -% \removebottomthings -% \fi -% \fi} - -%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% -% {\setxvalue{\@@tblprefix#1:#2:l}{\TBLlevel}% -% \long\setvalue{\@@tblprefix#1:#2:t}% -% {\doifdefined{\@@tblprefix#1:#2:l} -% {\edef\TBLlevel{\getvalue{\@@tblprefix#1:#2:l}}}% -% #3}} - -\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} - -\presetlocalframed[\@@tbl\@@tbl] - -\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 - % 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 - \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} -\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 - \expanded{\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{\expanded{\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=]% - \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 foot, dus state var - -\long\def\bTABLEhead{\dosingleempty\doTABLEhead} -\long\def\bTABLEnext{\dosingleempty\doTABLEnext} -\long\def\bTABLEbody{\dosingleempty\doTABLEbody} -\long\def\bTABLEfoot{\dosingleempty\doTABLEfoot} - -\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 - \def\bTR{\dodoubleempty\parseTR}% - \def\bTD{\dodoubleempty\parseTD}% - \def\bTH{\dodoubleempty\parseTH}% - \def\bTN{\dodoubleempty\parseTN}} - -% permits \expanded{\bTD ... \eTD} - -\unexpanded\def\eTR{} -\unexpanded\def\eTD{} -\unexpanded\def\eTH{} -\unexpanded\def\eTN{} - -\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 - \expanded{\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 - \expanded{\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}} - -\setupTABLE - [\c!frameoffset=.5\linewidth, - \c!backgroundoffset=\v!frame, - \c!framecolor=\s!black, - \c!color=, - \c!style=, - \c!headstyle=\v!bold, - \c!headcolor=, - \c!strut=\v!yes, - \c!autostrut=\v!no, - \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!color=, - \c!style=, - \c!headstyle=, - \c!headcolor=, - \c!strut=\v!no, - \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/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<>} +%D \showsetup{<>} +%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<>} +%D \showsetup{<>} +%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<>} -%D \showsetup{<>} -%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.mkii b/tex/context/base/core-sec.mkii deleted file mode 100644 index 960de366f..000000000 --- a/tex/context/base/core-sec.mkii +++ /dev/null @@ -1,2620 +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 - -\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 - % but we don't want color to influence user commands - % todo: get the if-else out of it - \getvalue{\??ko#1\c!command} - {} % no number - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \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 - \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 - % but we don't want color to influence user commands - \getvalue{\??ko#1\c!command}% - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \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 - \dostopattributes} - {\dostartattributes{\??ko#1}\c!style\c!color\empty - \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 - \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!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.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 - -\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.tex b/tex/context/base/core-sec.tex new file mode 100644 index 000000000..6cc0fbbf9 --- /dev/null +++ b/tex/context/base/core-sec.tex @@ -0,0 +1,2572 @@ +%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} + +\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\pagebreakdisabledtrue + \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 +% \ifpagebreakdisabled +% \global\pagebreakdisabledfalse +% \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 + \ifpagebreakdisabled + \global\pagebreakdisabledfalse + \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 + +\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 + % but we don't want color to influence user commands + % todo: get the if-else out of it + \getvalue{\??ko#1\c!command} + {} % no number + {\dostartattributes{\??ko#1}\c!style\c!color\empty + \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 + \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 + % but we don't want color to influence user commands + \getvalue{\??ko#1\c!command}% + {\dostartattributes{\??ko#1}\c!style\c!color\empty + \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 + \dostopattributes} + {\dostartattributes{\??ko#1}\c!style\c!color\empty + \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 + \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 + \postponenotes + \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!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-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: -\ifx\pdfkeeplinedimen\undefined +% \def\doinhibitblank +% {\kern\noblanksignal} - \let\mksetupgridsnapping \relax - \let\mkenablegridsnapping \relax - \let\mkdisablegridsnapping\relax +% \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\mksetupgridsnapping - {\pdfeachlineheight \openstrutheight - \pdfeachlinedepth \openstrutdepth - \pdffirstlineheight \pdfeachlineheight - \pdflastlinedepth \pdfeachlinedepth} +\def\dotoggleindentation + {\gdef\checkindentation{\global\indentationfalse\notoggleindentation\donoindentation}} - \def\mkenablegridsnapping - {\pdfkeeplinedimen\maxdimen - \topskip\strutht - \offinterlineskip} +\def\notoggleindentation + {\gdef\checkindentation{\global\indentationtrue\dotoggleindentation}} - \def\mkdisablegridsnapping - {\pdfkeeplinedimen\zeropoint - % reset topskip - \oninterlineskip} +\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 \ 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\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\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} + +% 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\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\dosetstretch#1% to be interfaces - {\relax\ifdim#1>\zeropoint - \dosetattribute{kern-chars}{\number\dimexpr#1\relax}% +\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} -% experimental mirroring +\defineindentingmethod [\v!yes] {\parindent\ctxparindent\relax} % no \indent ! +\defineindentingmethod [\v!always] {\parindent\ctxparindent\relax} % no \indent ! -\defineattribute[mirror] +\defineindentingmethod [\v!never] {\parindent\zeropoint\relax % no \indent ! + \chardef\indentingtoggle\zerocount} -\def\setcharactermirroring - {\ctxlua{mirror.enabled=true}% - \gdef\setcharactermirroring[##1]{\dosetattribute{mirror}{\number##1}}% - \setcharactermirroring} +\defineindentingmethod [\v!odd] {\chardef\indentingtoggle\plusone} +\defineindentingmethod [\v!even] {\chardef\indentingtoggle\plustwo} -\def\resetcharactermirroring - {\doresetattribute{mirror}} +\defineindentingmethod [\v!normal] {\ifx\normalindentation\empty\else + \let\currentindentation\normalindentation + \simplesetupindenting + \fi} -\newtoks\everysetupdirections +\defineindentingmethod [\v!reset] {\indentfirstparagraphtrue + \parindent\zeropoint + \chardef\indentingtoggle\zerocount} -\def\setupdirections[#1]% there will be more like setting up directions themselves - {\getparameters[\??di][#1]% - \the\everysetupdirections} +\def\noindenting{\indenting[\v!no, \v!next ]} +\def\doindenting{\indenting[\v!yes,\v!first]} -\chardef\directionsbidimode=0 +%D This one sets up the local indentation behaviour (i.e. either or not +%D a next paragraph will be indented). -\letvalue{\??di:bidi:\v!off }\zerocount -\letvalue{\??di:bidi:\v!global}\plusone -\letvalue{\??di:bidi:\v!local }\plustwo -\letvalue{\??di:bidi:\v!on }\plustwo +\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} + +\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 - \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 + \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} -% bidi: local=obey grouping, global=ignore grouping (unicode has no grouping) +\def\autoindentation + {\global\chardef\recheckindentationmode\plusone} -\setupdirections % maybe start/stop - [bidi=\v!off] +%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 + -\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}} +%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}). -\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} +%D Hm ... todo: -% test at end of file +\sfcode`\)=0 +\sfcode`\'=0 +\sfcode`\]=0 -% for the moment: \setcharactermirroring[\plusone] +\def\setfrenchspacing#1% + {\sfcode`\.#1 \sfcode`\,#1\relax + \sfcode`\?#1 \sfcode`\!#1\relax + \sfcode`\:#1 \sfcode`\;#1\relax} -% experimental spacing +\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 \ 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} % -% test: oeps {\setcharacterspacing[frenchpunctuation]x: xx \bfd x: xx} oeps: test +% 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\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\setcharacterspacing - {\ctxlua{spacings.enabled=true}% - \gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}% - \setcharacterspacing} +\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\resetcharacterspacing - {\doresetattribute{spacing}} +\def\startunpacked + {\blank + \leavevmode + \bgroup} -\letvalue{\??ch:\s!reset}\minusone +\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. -% \setcharacterspacing[frenchpunctuation] -% «\type{bla}»\crlf « \type{bla}»\crlf -% «bla »\crlf « bla»\crlf « bla »\crlf -% bla: bla\crlf bla : bla +\def\toonregelcorrectie{\showbaselinecorrection} +\def\regelcorrectie {\baselinecorrection} -\definecharacterspacing [frenchpunctuation] % name may change / unit is em +% \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} -\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} -% more +\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 % -% {\setcharacterkerning[extrakerning]\input davis\relax} +% 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 -\defineattribute[kern] +\ifdefined\globalbodyfontsize\else + \newdimen\globalbodyfontsize + \globalbodyfontsize=12pt +\fi -\newcount \maxcharacterkerningid +\ifx\normalizedbodyfontsize\undefined + \def\normalizedbodyfontsize{12pt} +\fi -\def\definecharacterkerning - {\dosingleargument\dodefinecharacterkerning} +% 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\dodefinecharacterkerning[#1]% - {\ifcsname\??ck#1\endcsname \else - \global\advance\maxcharacterkerningid\plusone - \setxvalue{\??ck:#1}{\the\maxcharacterkerningid}% +\def\topskipcorrection + {\simpletopskipcorrection + \vskip-\struttotal + \verticalstrut} + +\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\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\dosetupcharacterkerning[#1][#2]% - {\ifcsname\??ck:#1\endcsname - \begingroup - \getparameters[\??ck][\c!factor=0,#2]% - \ctxlua{kerns.setspacing(\getvalue{\??ck:#1},\@@ckfactor)}% +\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\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 + +\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 + {\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: +% +% \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} + +\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 + \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=} + +\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\setcharacterkerning - {\ctxlua{kerns.enabled=true}% - \gdef\setcharacterkerning[##1]{\dosetattribute{kern}{\csname\??ck:##1\endcsname}}% - \setcharacterkerning} +\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 + +\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} -\letvalue{\??ck:\s!reset}\minusone +% 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:) -\definecharacterkerning[extrakerning] +\newif\ifpagechanged \let\lastchangedpage\empty -\setupcharacterkerning[extrakerning][\c!factor=.125] +\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} -% sorry, here: +\def\changedpagestate#1#2% + {\executeifdefined{#2:p:#1}{0}} -% test \WORD{test TEST \TeX} test -% test \word{test TEST \TeX} test -% test \Word{test TEST \TeX} test +\def\checkpagechange#1{\docheckpagestatechange{#1}\s!paragraph\nofraggedparagraphs} +\def\changedpage #1{\changedpagestate{#1}\s!paragraph} -\defineattribute[case] +% saved struts -\def\setcharactercasing - {\ctxlua{cases.enabled=true}% - \gdef\setcharactercasing[##1]{\dosetattribute{case}{\number##1}}% - \setcharactercasing} +\ifx\savedstrutbox\undefined \newbox\savedstrutbox \fi -\def\WORD {\groupedcommand{\setcharactercasing[\plusone ]}{}} -\def\word {\groupedcommand{\setcharactercasing[\plustwo ]}{}} -\def\Word {\groupedcommand{\setcharactercasing[\plusthree]}{}} -\def\Words{\groupedcommand{\setcharactercasing[\plusfour]}{}} +\def\savestrut {\setbox\savedstrutbox\copy\strutbox} +\def\savedstrut{\copy \savedstrutbox} -\let\WORDS\WORD -\let\words\word +\chardef\bottomraggedness=0 % 0=ragged 1=normal/align 2=baseline -% \definestartstop is not yet in available at core-spa time -% -% \startrandomized \input tufte \stoprandomized -% -% \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=] +\def\bottomalignlimit{3\lineheight} -\def\randomizetext{\groupedcommand{\dosetattribute{case}{8}}{}} +\newif\ifn@rmalbottom +\newif\ifr@ggedbottom +\newif\ifb@selinebottom -% compound stuff (under construction) +\def\normalbottom + {% \topskip 10pt + \r@ggedbottomfalse} -\defineattribute[breakpoint] +\def\raggedbottom + {\chardef\bottomraggedness\zerocount + \n@rmalbottomfalse + \r@ggedbottomtrue + \b@selinebottomfalse + \settopskip} -\newbox\breakpointbox +\def\alignbottom + {\chardef\bottomraggedness\plusone + \n@rmalbottomtrue + \r@ggedbottomfalse + \b@selinebottomfalse + \settopskip} -\definesystemvariable {bp} % BreakPoint +\def\baselinebottom + {\chardef\bottomraggedness\plustwo + \n@rmalbottomfalse + \r@ggedbottomfalse + \b@selinebottomtrue + \settopskip} -\exhyphenchar=\minusone % we use a different order then base tex, so we really need this +\let\normalbottom=\alignbottom % downward compatible -\newcount \maxbreakpointsid +% new code, not in use yet -\def\definebreakpoints - {\dosingleargument\dodefinebreakpoints} +% 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 -\def\dodefinebreakpoints[#1]% - {\ifcsname\??bp:#1\endcsname \else - \global\advance\maxbreakpointsid\plusone - \setxvalue{\??bp:#1}{\the\maxbreakpointsid}% - \fi} +% 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) -\def\installbreakpoint - {\dotripleempty\doinstallbreakpoint} +% penalty: +% +% larger wins -% hm, we cannot prebuild lists, font dependent +% order: +% +% larger wins -\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 - \fi} +\registerctxluafile{core-spa}{1.001} -\def\setbreakpoints - {\ctxlua{breakpoints.enabled=true}% - \gdef\setbreakpoints[##1]{\dosetattribute{breakpoint}{\csname\??bp:##1\endcsname}}% - \setbreakpoints} +\definesystemattribute[kern-chars] +\definesystemattribute[skip-category] +\definesystemattribute[skip-penalty] +\definesystemattribute[skip-order] +\definesystemattribute[snap-category] +\definesystemattribute[display-math] -\letvalue{\??bp:\s!reset}\minusone +% \start \dosetstretch{.25em} \setuptolerance[tolerant,stretch] \input tufte \endgraf \stop +% \start \dosetstretch{.5em} effe flink doorfietsen \stop -\definebreakpoints[compound] +\def\dosetupgridsnapping % calls too often, only needed in gridsnapping + {\ctxlua{nodes.setsnapvalue(1,\number\openstrutheight,\number\openstrutdepth)}} -\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\doenablegridsnapping + {\dosetattribute{snap-category}{1}% + \topskip\strutht + \offinterlineskip} -% \setbreakpoints[compound] +\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 + +% 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} -\starttext +\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 \ 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 : @@ -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-tab.tex b/tex/context/base/core-tab.tex deleted file mode 100644 index 2e843eae8..000000000 --- a/tex/context/base/core-tab.tex +++ /dev/null @@ -1,2499 +0,0 @@ -%D \module -%D [ file=core-tab, -%D version=1997.10.10, -%D title=\CONTEXT\ Core Macros, -%D subtitle=\TABLE\ Embedding, -%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 / TaBlE Embedding} - -% By now it makes more sense to merge the patches into the original -% and clean that one up too. - -% Don't change the splitter: -% -% ... \NR -% \TABLEnoalign{\page}\TABLEhead -% \NC ... - -% e-tex: reverse rows or vadjust or ... in tables -% \ifalign -% \xhrule : calls for 'special' with width -% BUG: -% -% \starttable[|l|l|] -% \HL -% \RL\FR \VL Head 1 \VL Head 2 \VL\FR -% \RL\LR \VL Head A \VL Head B \VL\LR % niet grijs ?? -% \HL -% \VL 1 \VL 2 \VL\FR -% \VL a \VL b \VL\LR -% \HL -% \stoptable - -% melden als in kleur conflict, uitgestelde test op \SR\SR - -% verengelsen -% interface - -% footnotes flushen -% \......TABLE........ namen -% kolommen testen -% unbreakable kop definieren -% voetnoten -% meldingen -% als direct \use{max} dan fout -% \BREAKPOINT -% breedte lijn telt -% errors: ook gray in handle - -% \AR -> als in DL dan \DR - -% nieuw: -% -% \NL / \NL[blanko] is skip, nog default? -% geen \HL in a row -% \HL[n] -% \VL[n] + remembers -% c{colorspec} key -% \HC[color][width] -% \VC[color] -% meldingen row, column, use, advise -% \AR: UITSTELLEN / EXPERIMENTEEL - -% WAARDELOZE ERROR HANDLER -% THIS RENEWED MODULE WORKS OK BUT STILL LOOKS BAD - -%D We felt no need to write our own table building macros, -%D simply because Michael Wichura made a terrific one. This -%D package is quite complete and well documented. In \CONTEXT\ -%D we provide a shell for consistent spacing as well as color -%D support. Implementing these features without adapting the -%D original macros is not trivial. One easilly gets conflicts -%D with \type{\omit}, \type{\span} and \type{\noalign}, which -%D means that we end up postponing and overloading macros, -%D mostly global. Now, let's start with loading the main -%D macros: - -\doifundefined{BeginTable}{\doinputonce{table.tex}} - -\unprotect - -%D \macros -%D {inintable, ifsplittables} -%D -%D First we declare some variables. These show a bit what we -%D are dealing with. First we introdoce some booleans that -%D enable us, inside as well as outside this module, to -%D determine in what mode we are. - -\newif\ifintable -\newif\ifsplittables - -%D \macros -%D {tracetablestrue} -%D -%D When I documented this module, I felt the need for tracing -%D options. After implementing this feature, I also added -%D warnings, error recovery and automatic spacing. - -\newif\iftracetables - -%D We show this feature in an eample that also shows some of -%D the basic table typesetting commands. -%D -%D \startbuffer -%D \starttable[|||] -%D \HL -%D \VL first \VL second \VL\AR -%D \HL -%D \VL alfa \VL 1 \VL\AR -%D \VL beta \VL 2 \VL\AR -%D \VL gamma \VL 3 \VL\AR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \startcombination -%D {\tracetablesfalse\getbuffer} {\type{\tracetablesfalse}} -%D {\tracetablestrue\getbuffer} {\type{\tracetablestrue}} -%D \stopcombination -%D -%D This table is specified as: -%D -%D \typebuffer -%D -%D This examples shows about the minimum of commands needed to -%D typeset such a table. In this table, the \type {\AR} is -%D automatically translated into the more primitive (but more -%D verbose) commands \type {\SR}, \type {\FR}, \type {\MR} and -%D \type {\LR} commands. -%D -%D \startbuffer -%D \starttables[|||] -%D \HL -%D \VL first \VL second \VL\AR -%D \HL -%D \VL alfa \VL 1 \VL\AR -%D \VL beta \VL 2 \VL\AR -%D \VL gamma \VL 3 \VL\AR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D When we use the split table feature, we get a bit more -%D information. -%D -%D {\tracetablesfalse\getbuffer} -%D -%D Sometimes in tables information shows up that is not typed -%D in by the user. These messages give a cue in what aspect a -%D table definition is wrong. -%D -%D \startbuffer -%D \starttable[||||] -%D \HL -%D \VL first second \VL third \VL\AR -%D \HL -%D \VL alfa \VL 1 \VL a \VL\AR -%D \VL beta \VL 2 \VL b \VL -%D \VL gamma \VL \THREE{3} c \VL\AR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \typebuffer -%D -%D Those terrible table has three errors, which all show up in -%D typeset messages. Errors cannot always recovered 100\% and -%D therefore can result in two or more succesive messages, like -%D in the last row. -%D -%D \getbuffer - -%D Bringing color into tables is complicated by the mere fact -%D that color is not part of \TEX. The main complication is -%D that we don't know in advance how wide a column will be. I -%D implemented color support in tables in the early 90's -%D because I needed it for some articles on color. I have to -%D admit that I seldom use the mechanism. -%D -%D Most color support in \CONTEXT\ makes use of colored rules. -%D At first sight, one is tempted to implement colors in tables -%D in a similar way, but as said, we don't know the dimensions -%D in advance. It turns out however that we don't have to, -%D simply because alignments take care of stretching rules to -%D the appropritate dimensions. This means that we can provide -%D backgrounds by coloring rules with the height of a row, -%D skipping upwards and finally drawing the content, like in: -%D -%D \gdef\ShowExample -%D {\startfiguretext -%D {none} -%D {\getbuffer} -%D \typebuffer -%D \stopfiguretext} -%D -%D \startbuffer -%D \starttable[|c|c|] -%D \HL -%D \BL[2] \SR -%D \VL test \VL test \VL\SR -%D \HL -%D \VL test \VL test \VL\FR -%D \VL test \VL test \VL\MR -%D \VL test \VL test \VL\LR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D Just to be complete we show how the other columns can be -%D given a background. Later we will provide more details over -%D the commands used. -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \HL -%D \BL[3] \SR -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \HL -%D \BC \BL[2] \SR -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \HL -%D \BC \BC \BL \SR -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \HL -%D \BC \BL \SR -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \BL \BL \SR -%D \HL -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample - -%D In these examples we can clearly see that for being a real -%D background, the color or gray specification has to precede -%D the content. Just to keep things simple, we can recall this -%D specification later on: -%D -%D \startbuffer -%D \starttable[|c|c|c|] -%D \BC \BL \SR -%D \HL -%D \VL test \VL test \VL test \VL\SR -%D \HL -%D \BR\FR -%D \VL test \VL test \VL test \VL\FR -%D \BR\MR -%D \VL test \VL test \VL test \VL\MR -%D \BR\LR -%D \VL test \VL test \VL test \VL\LR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D Close study learns that we can put the specification -%D before or after the \type{\HL}, whatever suits best. Keeping -%D track of these specifications is taken care of by the next -%D variables: - -\newif \ifTABLEgrayline % executing gray line -\newif \ifTABLEgraydone % gray line executed -\newtoks \TABLEgraytoks % gray line specification - -\newif\ifTABLEinbreak - -%D Nog vervangen: - -\def\c!Table{Table} -\def\m!TABLE{TABLE} - -%D We already saw that the table macros report errors and -%D provide automatic spacing. These features can only be -%D implemented by keeping track of the state, often the last -%D command on a row. - -\chardef\TABLEunknown = 0 - -\chardef\TABLEseparaterow = 1 -\chardef\TABLEfirstrow = 2 -\chardef\TABLEmidrow = 3 -\chardef\TABLElastrow = 4 -\chardef\TABLErule = 5 -\chardef\TABLEskip = 6 -\chardef\TABLEautorow = 7 - -\chardef\TABLEforcefirstrow = 1 -\chardef\TABLEforcelastrow = 2 - -\chardef\TABLEmissingrow = 1 -\chardef\TABLEmissingcolumn = 2 -\chardef\TABLEspanoverflow = 3 -\chardef\TABLEdivisionoverflow = 4 - -%D We store these states using efficient \type {\chardef}'s. -%D Like most variables, these are global ones. When needed, -%D especially when we flush the backgrounds, we can temporary -%D disable the assignment. - -\newif\ifsetTABLEaction - -\def\setTABLEaction#1% - {\ifsetTABLEaction\global\chardef\TABLEaction#1\fi} - -\def\setTABLEforce#1% - {\ifsetTABLEaction\global\chardef\TABLEforce#1\fi} - -\def\setTABLEerror#1% - {\global\chardef\TABLEerror#1} - -%D Before we come to using these variables, we redefine and/or -%D adapt some \TABLE\ macros. Within \TABLE's the \type{|} and -%D \type{"} have special meanings in templates and are active -%D during. Their meaning can therefore conflict with those -%D elsewhere defined. To be compatible with traditional \TABLE\ -%D as well as \CONTEXT's \type{||} and the active \type{"} -%D extensions for my german friends, we do some catcode magic. - -\newif\ifForgetTableBarAndQuote \ForgetTableBarAndQuotetrue - -% \bgroup - -% \catcode`\|=\@@active -% \catcode`\"=\@@active -% -% \gdef\pushouterbarandquote -% {\ifForgetTableBarAndQuote -% \ifnum\catcode`\|=\@@active \let\outertablebar |\else\let\outertablebar \relax\fi -% \ifnum\catcode`\"=\@@active \let\outertablequote"\else\let\outertablequote\relax\fi -% \let|\letterbar -% \let"\letterdoublequote -% \fi} -% -% \gdef\popouterbarandquote -% {\ifForgetTableBarAndQuote -% \ifx\outertablebar \relax\else\let|\outertablebar \fi -% \ifx\outertablequote\relax\else\let"\outertablequote\fi -% \else -% \redefinetablebarandquote -% \fi} -% -% \egroup -% -% \def\ObeyTableBarAndQuote -% {\ForgetTableBarAndQuotefalse -% \ifintable -% \redefinetablebarandquote -% \fi} - -\let\ActivateBarAndQuote \relax -\let\ObeyTableBarAndQuote\relax -\let\pushouterbarandquote\relax -\let\popouterbarandquote \relax - -%D \macros -%D {ObeyTableBarAndQuote} -%D -%D As said, the \type{|} and \type{"} active characters are -%D often used for other purposes. By default, the outside -%D meanings are therefore preserved and available inside -%D tables. If for some reason one wants to use the \TABLE\ -%D primitives, one can say: -%D -%D \starttyping -%D \ObeyTableBarAndQuote -%D \stoptyping -%D -%D To keep things verbose, as well as to show what \TABLE\ -%D commands we affect, we show some meanings. - -\def\normalTABLEshortrule {\!ttShortHrule} % \- -\def\normalTABLElongrule {\!ttLongHrule} % \= -\def\normalTABLEfullrule {\!ttFullHrule} % \_ -\def\normalTABLEendofrow {\!ttEndOfRow} % \\ -\def\normalTABLEsimplebar {\unskip\!ttRightGlue&&} % | -\def\normalTABLEcomplexbar {\unskip\!ttRightGlue&\omit\!ttAlternateVrule} % \| -\def\normalTABLEquote {\unskip\!ttRightGlue&\omit&} % " -\def\normalTABLElineformat {\normalTABLEendofrow+} -\def\normalTABLElineending {\normalTABLEendofrow0 } -\def\normalTABLEsinglerule {&\normalTABLElongrule&} -\def\normalTABLEmultirule#1{&\use{#1}\normalTABLElongrule&} - -%D The next hack is dedicated to Tobias, who found out that -%D paragraph entries don't break well. - -\def\TABLEhack{\hskip\zeropoint} - -%D The first attemp to solve this problem was: -%D -%D \starttyping -%D \def\normalTABLEquote% -%D {\unskip\TABLEhack\!ttRightGlue&\omit&\TABLEhack} -%D \stoptyping -%D -%D But, as usual, this interfered with \type {\omit}. -%D -%D The next attempt is redefining some core \TABLE\ macro:. -%D This works ok, but breaks for instance the~\type{b} -%D key handling. -%D -%D \starttyping -%D \def\!tfAdjoinPriorColumn% -%D {\ifnum\!taColumnNumber=0 -%D \!taPreamble=\!taRuleColumnTemplate -%D ... -%D \if!taOnceOnlyTabskip -%D \!thToksEdef\!taDataColumnTemplate= -%D {\TABLEhack####\TABLEhack\tabskip\the\!taLastRegularTabskip} -%D \else -%D \!taDataColumnTemplate{\TABLEhack##\TABLEhack}% -%D \fi -%D ... -%D \ReadFormatKeys} -%D \stoptyping - -% \newdimen\TABLEparheight - -\def\BeginTableParBox#1% - {\setbox\scratchbox\vtop\bgroup % \setbox added - \hsize#1\relax - \normalbaselines - \let~\!ttTie - \let\-\!ttDH - \blank[\v!disable]% % added - \the\EveryTableParBox} - -\def\EndTableParBox - {\removelastskip % itemize or so - \endgraf - \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 - \vtop to \noflines\lineheight{\box\scratchbox}% - \fi % esp between rows - \else % of paragraphs - \egroup - \fi -% \getboxheight\scratchdimen\of\box\scratchbox\relax% compensate for -% \ifdim\scratchdimen>\TABLEparheight % funny depth of -% \global\TABLEparheight\scratchdimen % multi-line box -% \fi % i.e. vtop - \box\scratchbox} - -% We also need to patch away the interfering math switch: - -% \mathpunctuationtrue - -% test, test -% \starttable[|c|] -% \NC1,,10\NC\AR -% \stoptable -% test, test - -\def\!ttBeginTableA[#1]{% - \if #1u% % "unboxed" table - \ifmmode - \def\!ttEndTable{% % user had better be in display math mode - \relax}% % and have only one table at the outer level - \else % user had better be in vertical mode - \bgroup - \def\!ttEndTable{% - \egroup}% - \fi - \else - %\hbox\bgroup $ - %\def\!ttEndTable{% - % \egroup % for the \vtop, \vbox, or \vcenter, yet to come - % $% for math mode - % \egroup}% for the \hbox - %\if #1t% - % \vtop - %\else - % \if #1b% - % \vbox - % \else - % \vcenter % math mode was essential for this - % \fi - %\fi - % - \hbox\bgroup - \def\!ttEndTable{\egroup\egroup}% - \if#1t% - \vtop - \else\if#1b% - \vbox - \else - \def\!ttEndTable{\egroup$\egroup}% - %$\vcenter - \scratchtoks\everymath\everymath\emptytoks$\everymath\scratchtoks\vcenter - \fi\fi - % - \bgroup % for the \vtop, \vbox, or \vcenter - \fi - \advance\!taRecursionLevel 1 % RecursionLevel governs initialization - \let\!ttRightGlue=\relax % This may be changed by \JustCenter, etc - \everycr\emptytoks % ={} - \ifnum \!taRecursionLevel=1 - \!ttInitializeTable - \fi} - -%D The next redefinition is more robust than the original: - -\def\SetTableToWidth#1% - {\doifelsenothing{#1}{\!taTableSpread\emptytoks}{\!taTableSpread{to #1}}} - -% (*) Try this one with \type {direction} and {girection}; -% the \PPCHTEX\ manual is a nice testcase. -% -% \startoverlay -% {\starttable[ | l w(2cm) | w(8cm) | ] -% \HL -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \MR -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \LR -% \HL -% \stoptable} -% {\starttable[ | l w(2cm) | p(8cm) | ] -% \HL -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \MR -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \LR -% \HL -% \stoptable} -% \stopoverlay -% \vskip2cm -% \starttable[ | l w(2cm) | p(8cm) | ] -% \HL -% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR -% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \LR -% \HL -% \stoptable -% \vskip2cm -% \starttable[ | l w(2cm) | p(8cm) | ] -% \HL -% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \FR -% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \LR -% \HL -% \stoptable - -%D To give an impression of what the (well documented) source -%D of \TABLE\ looks like, we first implement an alternative for -%D the numeric keys. The quantity keys (\type{q} and \type{Q}) -%D support the more european way of writing numbers: -%D -%D \startnarrower -%D 100.000.000,00 instead of 100,000,000.00 -%D \stopnarrower -%D -%D The next table shows how to use these keys. We use braces -%D instead of brackets because we need brackets to specify the -%D format. -%D -%D \startbuffer -%D \starttable{|q[00,000]|Q[00,00]|} -%D \HL -%D \VL -1,2 \VL 12,35 \VL\FR -%D \VL 11,203 \VL 2,4 \VL\LR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample -%D -%D Although a more efficient implementation is possible |<|we -%D can for instance share common macros|>| we just adapt a copy -%D of the numeric ones. To permit double loading of this -%D module, we check for the existence of one of the macros. - -\letvalue{!tk<\string q>}=\undefined -\letvalue{!tk<\string Q>}=\undefined - -%D We just copy the original {\em comments}. -%D -%D \em Key \type{q}: quantity item, non||math mode. - -\NewFormatKey q% - {\letempty\!tqStyle - \futurelet\!tnext\!tqTestForBracket} - -%D \em Key \type{Q}: quantity item, math mode. - -\NewFormatKey Q% - {\def\!tqStyle{$}% - \futurelet\!tnext\!tqTestForBracket} - -%D \em Note: the space between a quantity entry and the -%D following \type{|}, \type{"}, or \type{\|} is mandatory. -%D empty quantity entries are not allowed: use \type{{}} or -%D \type{\omit} instead. -%D -%D \em Test for bracket: invoked by the keys \type{q} and -%D \type{Q}. - -\def\!tqTestForBracket - {\ifx[\!tnext - \!thx\!tqGetArgument - \else - \!thx\!tqGetCode - \fi} - -%D \em Get code: e.g. \type{4}, or \type{4,0}, \type{0,4}, or -%D \type{10,2}. - -\def\!tqGetCode#1 % note the blank - {\!tqConvertCode #1,,!} - -%D \em Convert code: e.g. converts above to \type{[0000]}, -%D \type{[0000,]}, \type{[,0000]}, \type{[0000000000,00]}. - -\def\!tqConvertCode #1,#2,#3!% - {\begingroup - \aftergroup\edef - \aftergroup\!ttemp - \aftergroup{% - \aftergroup[% - \!taCountA #1 - \!thLoop - \ifnum \!taCountA>\zerocount - \advance\!taCountA \minusone - \aftergroup0 - \repeat - \def\!ttemp{#3}% - \ifx\!ttemp\empty - \else - \aftergroup, - \!taCountA #2 - \!thLoop - \ifnum\!taCountA>\zerocount - \advance\!taCountA \minusone - \aftergroup0 - \repeat - \fi - \aftergroup]\aftergroup}% - \endgroup\relax - \!thx\!tqGetArgument\!ttemp} - -%D \em Get argument: -%D -%D \starttyping -%D -%D \stoptyping - -\def\!tqGetArgument[#1]% - {\!tqMakeQuantityTemplate\!tqStyle#1,,!} - -%D \em Make quantity template. - -\def\!tqMakeQuantityTemplate#1#2,#3,#4!% #1= or $ - {\def\!ttemp{#4}% - \ifx\!ttemp\empty - \!taDimenC\zeropoint - \else - \setbox0\hbox{\m@th #1,#3#1}% - \!taDimenC\wd0 - \fi - \setbox0\hbox{\m@th #1#2#1}% - \!thToksEdef\!taDataColumnTemplate - ={\noexpand\!tqSetQuantityItem{\the\wd0 }{\the\!taDimenC}{#1}% - \the\!taDataColumnTemplate}% - \ReadFormatKeys} - -%D \em Set numeric item. - -\def\!tqSetQuantityItem #1#2#3#4 % - {\!tqSetQuantityItemA{#1}{#2}{#3}#4,,!} - -\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}} - -%D Here ends the Q||extension. Did you watch the clever use -%D of aftergroup in \type{\!tqConvertCode}. - -% %D We also (have to) define a key for \type{\cap}: -% -% \letvalue{!tk<\string K>}=\undefined -% -% \NewFormatKey K% -% {\ReadFormatKeys b\smallcapped} - -%D A few pages back we saw backgrounds, further on we will see -%D colored rules, and here we provide a means to color the -%D entries in a column. (We can of course always use the normal -%D color commands for individual entries.) We could not use the -%D lowercase~\type{c}, because that one is used to force {\em -%D centering}. -%D -%D \startbuffer -%D \starttable[|C{red}|C{green}|C{blue}|] -%D \VL R(ed) \VL G(reen) \VL B(lue) \VL\SR -%D \stoptable -%D \stopbuffer -%D -%D \ShowExample - -\letvalue{!tk<\string C>}=\undefined - -\NewFormatKey C#1% - {\ReadFormatKeys b{\localstartcolor[#1]} a{\localstopcolor}} - -%D So now we have three new keys: -%D -%D \starttable[|||] -%D \HL -%D \NC \bf key \NC \bf meaning \NC\AR -%D \HL -%D \NC Q[x,y] \NC math mode formatted numbers \NC\AR -%D \NC q[x,y] \NC text mode formatted numbers \NC\AR -%D \NC C{identifier} \NC column entry color \NC\AR -%D \HL -%D \stoptable - -%D To be compatible with the tabulate environment, we also -%D support the \type {l}, \type {c} and \type {r} keys for -%D paragraph entries. - -\letvalue{!tk<\string l>}=\undefined -\letvalue{!tk<\string c>}=\undefined -\letvalue{!tk<\string r>}=\undefined -\letvalue{!tk<\string x>}=\undefined % not that needed - -\NewFormatKey c% - {\prependtoks\raggedcenter\to\!taDataColumnTemplate - \ReadFormatKeys \LeftGlue\hfil \RightGlue\hfil} - -\NewFormatKey l% - {\prependtoks\raggedright\to\!taDataColumnTemplate - \ReadFormatKeys \LeftGlue\empty \RightGlue\hfil} - -\NewFormatKey r% - {\prependtoks\raggedleft\to\!taDataColumnTemplate - \ReadFormatKeys \LeftGlue\hfil \RightGlue\empty} - -\NewFormatKey x% - {\prependtoks\notragged\to\!taDataColumnTemplate - \ReadFormatKeys \LeftGlue\hfil \RightGlue\empty} - -\appendtoks \TABLEparalignment \to \EveryTableParBox - -\def\!tfReFormat#1% - {\the \!taLeftGlue - \vbox{\forgetall\ialign{\span\the\!taDataColumnTemplate\cr#1\cr}}% - \the \!taRightGlue - \kern\zeropoint} % prevents \unskip / really needed - -%D Later on, we're going to implement multiple page table -%D support, therefore the next \TABLE\ macro needs to be -%D slightly adapted, i.c. the penalty is removed. We also -%D add basic color support. - -\def\!ttFullHruleA - {\!ttGetHalfRuleThickness - \startglobalTABLEcolor % added - \hrule\!thHeight\dimen0\!thDepth\dimen0 - \stopglobalTABLEcolor % added - %\penalty0 % removed - \egroup} - -%D We'll see that when we want to give a vertical rule a color, -%D we have to set and reset states. After heavy testing it -%D proved most useful to extend a \TABLE\ primitive with some -%D hooks. One thing to keep in mind is that \type{&} keeps -%D assignments local. Again, we add basic color support. - -\let\TABLEbeforebar\empty -\let\TABLEafterbar \empty - -\def\@VLn{1} -\def\@VLd{.125em} - -\def\do!ttInsertVrule % will be merged in 2005 - {\vrule \!thWidth - \ifnum\!tgCode=\plusone - \ifx\!tgValue\empty - \LineThicknessFactor - \else - \!tgValue - \fi - \LineThicknessUnit - \else - \!tgValue - \fi - \hskip\@VLd} - -\def\!ttInsertVrule - {\hfil - \TABLEbeforebar % added - \startglobalTABLEcolor % added - % we could do without this speedup, some day merge 'm - \ifcase\@VLn\or - \do!ttInsertVrule - \unskip - \else - \dorecurse\@VLn\do!ttInsertVrule - \gdef\@VLn{1}% - \unskip - \fi - \stopglobalTABLEcolor % added - \TABLEafterbar % added - \hfil - &} - -%D The next two macros are only adapted to basis rule -%D color support. - -\def\!tfSetVrule - {\!thToksEdef\!taRuleColumnTemplate= - {\noexpand\hfil - \noexpand\startglobalTABLEcolor % added - \noexpand\vrule - \noexpand\!thWidth - \ifnum\!tgCode=\plusone - \ifx\!tgValue\empty - \the\LineThicknessFactor - \else - \!tgValue - \fi - \!taLTU - \else - \!tgValue - \fi - ####% - \noexpand\hfil - \noexpand\stopglobalTABLEcolor % added - \the\!taRuleColumnTemplate}% - \!tfAdjoinPriorColumn} - -\def\!ttShortHruleA - {\!ttGetHalfRuleThickness - \startglobalTABLEcolor % added - \leaders\hrule\!thHeight\dimen0\!thDepth\dimen0\hfill - \stopglobalTABLEcolor % added - \null - \ignorespaces} - -%D We already showed the next one, but here we slightly adapt -%D the macro by adding an \type{\expandafter}. The space after -%D \type{#1} is crucial! - -\def\normalTABLEcomplexbar#1% - {\unskip\!ttRightGlue&\omit\expandafter\!ttAlternateVrule#1 } - -%D To get rid of interfering \type{\omit}'s when we are -%D checking the number of columns and reporting problems. The -%D extensions concern the second level check, the first -%D subbranch and advancing the column. - -\ifx\mscount\undefined \newcount\mscount \fi - -\def\!ttuse#1% - {\ifnum#1>\plusone - \omit - \global\TABLEdivisionfalse - \scratchcounter\currentTABLEcolumn % added - \advance\scratchcounter #1% % added - \advance\scratchcounter \minusone % added - \ifnum\scratchcounter>\maxTABLEcolumn % added - \def\next % added - {\setTABLEerror\TABLEspanoverflow % added - \handleTABLEerror}% % added - \else % added - \def\next % added - {\global\advance\currentTABLEcolumn #1% % added - \global\advance\currentTABLEcolumn \minusone % added - \mscount#1% \mscount is in Plain - \advance\mscount \minusone - \advance\mscount \mscount - \!thLoop - \ifnum\mscount>\plusone - \sp@n % from Plain (\span\omit \advance\mscount\m@ne) - \repeat - \span}% - \fi % added - \else % added - \def\next % conflicts with possible next \omit % added - {\global\advance\currentTABLEcolumn \plusone}% % added - \fi - \next} % added - -% \starttable[|c|c|c|c|] -% \HL -% \VL {test} \VL \TWO{} \VL test \VL\FR -% \DL \DC \DL\DR -% \VL {test} \VL \TWO{} \VL test \VL\LR -% \HL -% \stoptable - -%D All commands that are executed between rows are to be put in -%D \type {\noalign}. We can however not verify if we (that is -%D \TABLE) does or did not enter this mode. A moderate dirty -%D but useful trick is using our own alternative:\footnote{Once -%D one has entered the stage of redefining \TEX\ primitives, -%D such hacks become a second nature. However, redefining \type -%D {\omit} and \type{\span} is not that easy.} - -\def\TABLEnoalign - {\noalign\bgroup\let\noalign\relax\let\next=} - -%D \macros -%D {starttable} -%D -%D The rest of this module is not easy to comprehend, mainly -%D because we have to take care of: -%D -%D \startitemize[packed] -%D \item \type{\startitemize[template]} -%D \item \type{\startitemize{template}} -%D \item \type{\startitemize[predefined]} -%D \stopitemize -%D -%D as well as: -%D -%D \startitemize[continue] -%D \item restart after table break -%D \stopitemize -%D -%D The official specification of the start command is: -%D -%D \showsetup{starttable} - -\newconditional\tablerepeathead -\newconditional\tablerepeattail - -\def\starttable - {\bgroup - \doif\@@tisplit\v!auto - {\ifinsidesplitfloat\let\@@tisplit\v!yes\fi}% - \doifinsetelse\@@tisplit{\v!yes,\v!repeat} - {\def\stoptable{\stoptables\egroup}% - \starttables} - {\doifelsenothing\@@tiframe - {\ifinsidefloat\else\startbaselinecorrection\fi} - {\startframedcontent[\@@tiframe]}% - \postponefootnotes - \firststagestartTABLE}} - -\def\stoptable - {\chuckTABLEautorow % before the tail, else noalign problem - \insertTABLEtail - \TABLEnoalign{\globalletempty\@@TABLEhead}% - \TABLEnoalign{\globalletempty\@@TABLEtail}% - \finishTABLE - \doifelsenothing\@@tiframe - {\ifinsidefloat\else - \stopbaselinecorrection - \goodbreak % compensates all the nobreaks - \fi} - \stopframedcontent - \egroup} - -%D Before we can grab the argument, we have to make sure that -%D the \CATCODES\ are set. The first stage takes care of that. - -\def\firststagestartTABLE - {\bgroup % kan-ie weg? - \global\intabletrue - \pushouterbarandquote - %catcode`\|=\@@other - \complexorsimple\secondstagestartTABLE} - -\def\simplesecondstagestartTABLE#1% - {\complexsecondstagestartTABLE[{#1}]} - -%D \macros -%D {definetabletemplate} -%D -%D The complex (and main) start macro first takes care of the -%D predefined case. Such a predefined setup looks like: -%D -%D \starttyping -%D \definetabletemplate[test][|||] -%D -%D \starttable[test] -%D \VL test \VL test \VL\AR -%D \VL test \VL test \VL\AR -%D \VL test \VL test \VL\AR -%D \stoptable -%D \stoptyping -%D -%D The implementation of the definition macro is not that -%D complicated: - -\def\definetabletemplate % to be redone - {\bgroup - \catcode`\|=\@@other - \doquadrupleempty\dodefinetabletemplate} - -\def\dodefinetabletemplate[#1][#2][#3][#4]% - {\ifsecondargument - \setgvalue{\c!Table#1}{\douseTABLEtemplate{#2}{#3}{#4}}% - \fi - \egroup} - -\def\douseTABLEtemplate#1#2#3% - {\gdef\TABLEhead{\getvalue{@@TABLEhead#2}}% - \gdef\TABLEtail{\getvalue{@@TABLEtail#3}}% - \complexsecondstagestartTABLE[#1]} - -%D The optional third and fourth arguments define which table -%D head and tail to use. -%D -%D \starttyping -%D \definetabletemplate[test][|||][before][after] -%D \stoptyping -%D -%D This also means that one can define table heads and tails -%D by name! -%D -%D \starttyping -%D \starttablehead[before] -%D \HL \VL first \VL second \VL \SR \HL -%D \stoptablehead -%D \stoptyping -%D -%D Templates defined this way get protected names, that cannot -%D conflict with existing commands. -%D -%D \showsetup{definetabletemplate} -%D -%D The second half of the next macro prepares table -%D splitting. - -\def\insertTABLEhead - {\TABLEnoalign{\global\settrue \preventTABLEbreak \global\setfalse\someTABLEhead}% - \TABLEhead - \TABLEnoalign{\global\setfalse\preventTABLEbreak}} - -\def\insertTABLEtail - {\TABLEnoalign{\global\settrue \preventTABLEbreak \global\setfalse\someTABLEtail}% - \TABLEtail - \TABLEnoalign{\global\setfalse\preventTABLEbreak}} - -% \def\dorestartTABLE#1% -% {\gdef\restartTABLE{#1}% -% \restartTABLE -% \insertTABLEhead -% \ifsplittables \ifconditional \tablerepeattail -% \TABLEnoalign{\goodbreak}% -% \insertTABLEtail -% \TABLEnoalign{\goodbreak}% -% \fi \fi} - -\def\verysimpleTableHL - {\TABLEnoalign{\expandafter\normalTABLEfullrule\@@tiHLheight}} - -\def\dorestartTABLE#1% - {\gdef\restartTABLE{#1}% - \restartTABLE - \TABLEnoalign{\globalpushmacro\simpleTableHL\global\let\simpleTableHL\verysimpleTableHL}% - \insertTABLEhead - \ifsplittables \ifconditional \tablerepeattail - \TABLEnoalign{\goodbreak}% - \insertTABLEtail - \TABLEnoalign{\goodbreak}% - \fi \fi - \TABLEnoalign{\globalpopmacro\simpleTableHL}} - -\bgroup \catcode`|=\@@other \catcode`"=\@@other - -\gdef\complexsecondstagestartTABLE#1[#2]% brr nested mess - {\bgroup - \@@useotherbar - \@@useotherquote - \global\setfalse\someTABLEhead - \global\setfalse\someTABLEtail - \expanded{\doifinstringelse{|}{#2}} - {\xdef\restartTABLE{\noexpand\dorestartTABLE{\noexpand\thirdstagestartTABLE{#2}}}} - {\doifdefinedelse{\c!Table#2} - {\gdef\restartTABLE{\getvalue{\c!Table#2}}} - {\gdef\restartTABLE{\dorestartTABLE{\getvalue{#2}}}}}% - \egroup - \restartTABLE} - -\egroup - -%D The third stage involves a lot of (re)sets, which we will -%D explain later. - -%D The next definition is convenient and more in tune with -%D \CONTEXT. - -\let \everytable \EveryTable - -%D We immediately use this register: - -\appendtoks - \fixedspaces - \let\_\normalunderscore -\to \everytable - -%D Now we can start the table. - -\def\thirdstagestartTABLE#1% - {\global\setTABLEactiontrue - \setTABLEaction\TABLEunknown - \setTABLEforce\TABLEunknown - \setTABLEerror\TABLEunknown - \global\TABLEgraylinefalse - \global\TABLEgraydonefalse - \globalletempty\TABLEgrayline - \globalletempty\nextTABLEgrayline - \globalletempty\TABLEgraylineerror - \globalletempty\TABLEgraylinestatus - \resetVLvalues - \appendtoks\popouterbarandquote\to\EveryTable - \appendtoks\localTABLEsetup\to\EveryTable - \BeginTable[\ifsplittables u\else b\fi]% - \defineTABLEunits - \defineTABLEsteps - \defineTABLErules - \defineTABLEdivisions - \defineTABLEshorthands - \defineTABLEbackgrounds - \defineTABLEendings - \forgetall % added - \doifsomething{#1} - {\def\TABLEformat{#1}% - \getTABLEnofcolumns\TABLEformat - % more modern is to use catcode tables - \expandafter\BeginFormat\TABLEformat\EndFormat}} - -\def\finishTABLE - {\chuckTABLEautorow - \unskip\crcr - \EndTable - \global\intablefalse - \egroup} - -%D \macros -%D {starttables} -%D -%D Split tables are specified using the plural form of the -%D start and stop commands. -%D -%D \showsetup{starttables} -%D -%D For example: -%D -%D \starttyping -%D \starttables[|||] -%D \HL -%D \VL element \VL atom weight \VL\AR -%D \HL -%D \VL ....... \VL ........... \VL\AR -%D \VL ....... \VL ........... \VL\AR -%D \HL -%D \stoptables -%D \stoptyping - -\newbox\tablecontentbox - -\def\starttables - {\bgroup - \splittablestrue - \doifelse\@@tisplit\v!repeat - {\settrue \tablerepeathead\settrue \tablerepeattail} - {\setfalse\tablerepeathead\setfalse\tablerepeattail}% - \flushnotes - \setbox\tablecontentbox\vbox\bgroup - \forgetall - \global\TABLEinbreakfalse - \firststagestartTABLE} - -% \def\stoptables -% {\ifconditional\tablerepeattail\else\insertTABLEtail\fi -% \finishTABLE -% \egroup -% \dosplittablebox\tablecontentbox -% \flushnotes -% \egroup} - -\def\stoptables - {\chuckTABLEautorow % AM: before the tail, else noalign problem - \ifconditional\tablerepeattail\else\insertTABLEtail\fi - \finishTABLE - \egroup - \dosplittablebox\tablecontentbox - \flushnotes - \egroup} - -\newdimen\TABLEcaptionheight % obsolete - -\def\dosplittablebox#1% - {\resettsplit - \def\tsplitminimumfreelines{2}% - \def\tsplitminimumfreespace{\TABLEcaptionheight}% - \setbox\tsplitcontent\box#1% - \ifconditional\tablerepeathead \ifconditional\someTABLEhead - \setbox\tsplithead\vsplit\tsplitcontent to \lineheight - \setbox\tsplithead\vbox{\unvbox\tsplithead}% - \fi \fi - \ifconditional\tablerepeattail \ifconditional\someTABLEtail - \setbox\tsplittail\vsplit\tsplitcontent to \lineheight - \setbox\tsplittail\vbox{\unvbox\tsplittail}% - \fi \fi - \ifinsidefloat\else - \def\tsplitbeforeresult{\startbaselinecorrection}% - \def\tsplitafterresult {\stopbaselinecorrection}% - \fi - \handletsplit} - -%D When the table in the previous example is split across -%D pages, only the first gets a head. We could have said -%D something like: -%D -%D \starttyping -%D \starttablekop -%D \HL -%D \VL element \VL atom weight \VL\AR -%D \HL -%D \stoptablekop -%D -%D \starttablestaart -%D \HL -%D \stoptablestaart -%D -%D \starttables[|||] -%D \VL ....... \VL ........... \VL\AR -%D \VL ....... \VL ........... \VL\AR -%D \stoptables -%D \stoptyping -%D -%D This time each split table gets a head line and ends with -%D a rule. Keep in mind that such heads also apply to the -%D unbroken ones and should be defined local (grouped) if -%D needed. The rather complicated definition below is due to -%D the fact that the stopcondition is interface language -%D dependant. - -\let\@@TABLEhead\empty \def\TABLEhead{\@@TABLEhead} -\let\@@TABLEtail\empty \def\TABLEtail{\@@TABLEtail} - -\letvalue{\e!start\v!tablehead}=\undefined -\letvalue{\e!stop \v!tablehead}=\undefined -\letvalue{\e!start\v!tabletail}=\undefined -\letvalue{\e!stop \v!tabletail}=\undefined - -\expanded - {\def\csname\e!start\v!tablehead\endcsname##1\csname\e!stop\v!tablehead\endcsname% - {\noexpand\setTABLEhead##1\noexpand\end}} - -\expanded - {\def\csname\e!start\v!tabletail\endcsname##1\csname\e!stop\v!tabletail\endcsname% - {\noexpand\setTABLEtail##1\noexpand\end}} - -%D The second argument is a dummy one, by scanning for it, we -%D get rid of interfering spaces. - -\def\setTABLEhead{\dodoubleempty\dosetTABLEhead} -\def\setTABLEtail{\dodoubleempty\dosetTABLEtail} - -\newconditional\preventTABLEbreak -\newconditional\someTABLEhead - -\def\dosetTABLEhead[#1][#2]#3\end{\setvalue{@@TABLEhead#1}{\TABLEnoalign{\global\settrue\someTABLEhead}#3}} -\def\dosetTABLEtail[#1][#2]#3\end{\setvalue{@@TABLEtail#1}{\TABLEnoalign{\global\settrue\someTABLEtail}#3}} - -%D Redudant \type{\HL}'s are removed automatically, so -%D mid||lines can be used without problems. - -%D We need an alternative for the normal complex or simple -%D commands, because assignments in these system commands -%D conflict with \type{\noalign}. This alternative is about -%D as efficient as possible. - -\def\complexorsimpleTable#1#2% - {\csname\if[\noexpand#2\s!complex\else\s!simple\fi\c!Table#1\endcsname#2} - -%D The next one is used in \type{\VL} cum suis and honours -%D the next grouping. - -\def\docomplexorsimpleTable#1#2% - {\ifx\next\bgroup\@EA#2\else\@EA\dodocomplexorsimpleTable\@EA#1\@EA#2\fi} - -\def\dodocomplexorsimpleTable#1#2#3% - {\if[\noexpand#3\@EA#1\else\@EA#2\fi#3} - -%D The order of the next macros is more or less random. First -%D we implement error recovery. Errors are reported to the -%D screen and log file as well as visualized in the table in -%D teletype. - -\def\handleTABLEerror - {\ifTABLEgrayline \else - \ifnum\TABLEerror=\TABLEunknown \else - \setTABLEaction\TABLEunknown - \globalletempty\checkTABLEautorow - \globalletempty\chuckTABLEautorow - \fi - \ifcase\TABLEerror - % no error - \or - % \TABLEmissingrow - \tttf [missing row]% - \writestatus\m!TABLE{missing row}% - \SR - \or - % \TABLEmissingcolumn - \fillTABLEcolumns - \tttf [missing column]% - \writestatus\m!TABLE{missing column}% - \SR - \or - % \TABLEspanoverflow - \fillTABLEcolumns - \tttf [columnspan too large]% - \writestatus\m!TABLE{columnspan too large}% - \SR - \or - % \TABLEdivisionoverflow - \fillTABLEcolumns - \tttf [division line too long]% - \writestatus\m!TABLE{division line too long}% - \SR - \fi - \fi - \ifnum\TABLEerror=\TABLEunknown \else - \finishTABLErow - \fi} - -\def\finishTABLErow - {\crcr - \TABLEnoalign - {\nobreak - \setTABLEaction\TABLEunknown - \setTABLEerror\TABLEunknown - \globalletempty\checkTABLEautorow - \globalletempty\chuckTABLEautorow - \global\currentTABLEcolumn\zerocount}} - -\def\fillTABLEcolumns - {\ifnum\currentTABLEcolumn>\maxTABLEcolumn \else - \global\advance\currentTABLEcolumn \plusone - \normalTABLEquote - \expandafter\fillTABLEcolumns - \fi} - -%D Next we enter the more complicated area of column and row -%D switching. I won't go into much detail from now on, but just -%D mention the general principles. -%D -%D \startitemize[3*ruim] -%D \sym{\type{\SR}} end a separate row (between rules) -%D \sym{\type{\FR}} end a first row (after a rule) -%D \sym{\type{\MR}} end a mid row (between text lines) -%D \sym{\type{\LR}} end a last row (before a rule) -%D \stopitemize -%D -%D and best of all: -%D -%D \startitemize[continue] -%D \sym{\type{\AR}} end a row with automatic spacing -%D \stopitemize -%D -%D As far as possible, we report confusing situations. In -%D most cases one can use \type{\AR}, which transfigurates -%D itself into one of the other types. -%D -%D \starttyping -%D \starttable[||] -%D \HL -%D \VL a separate row \VL\SR -%D \HL -%D \VL a first row \VL\FR -%D \VL a mid row \VL\MR -%D \VL a last row \VL\LR -%D \HL -%D \stoptable -%D \stoptyping -%D -%D In this example we could have used \type{\AR} without -%D problems. -%D -%D Color or gray scale backgrounds precede the content. They -%D are passed over horizontal (division) lines when needed. -%D Errors in the color template are traced elsewhere. Here we -%D only check for inconsistent spacing. Due to the way \TEX\ -%D handles alignments, we cannot automate spacing for colored -%D rows and columns. - -\chardef\TABLErowzero=0 - -\def\checkTABLErow#1% pure for message purposes - {\unskip % added - \ifTABLEgraydone - \defconvertedargument\asciia{#1}% - \defconvertedcommand \asciib\TABLEendBCL - \ifx\asciia\asciib \else - \writestatus\m!TABLE{confusing \asciia\space and \asciib}% - \gdef\TABLEgraylineerror% - {\globalletempty\TABLEgraylineerror - [\asciia\unskip<->\asciib\unskip]}% - \fi - \global\TABLEgraydonefalse - \fi} - -\def\defineTABLEendings - {\let\SR\TableSR - \let\FR\TableFR - \let\MR\TableMR - \let\LR\TableLR - \let\AR\TableAR} - -\def\TableSR - {\ifTABLEgrayline \else - \ifnum\TABLEaction=\TABLEfirstrow - \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% - \else\ifnum\TABLEaction=\TABLEmidrow - \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% - \else\ifnum\TABLEaction=\TABLEmidrow - \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% - \fi\fi\fi - \fi - \checkTABLErow\SR - \endTABLErow\TABLEseparaterow\TABLErowfactor\TABLErowfactor} - -\def\TableFR - {\ifTABLEgrayline \else - \ifnum\TABLEaction=\TABLEmidrow - \writestatus\m!TABLE{change \string\FR\space into \string\MR/\string\LR}% - \else\ifnum\TABLEaction=\TABLElastrow - \writestatus\m!TABLE{change \string\FR\space into \string\MR/\string\LR}% - \fi\fi - \fi - \checkTABLErow\FR - \endTABLErow\TABLEfirstrow\TABLErowfactor\TABLErowzero} - -\def\TableMR - {\ifTABLEgrayline \else - \ifnum\TABLEaction=\TABLErule - \writestatus\m!TABLE{change \string\MR\space into \string\FR/\string\SR}% - \else\ifnum\TABLEaction=\TABLElastrow - \writestatus\m!TABLE{change \string\MR\space into \string\FR}% - \fi\fi - \fi - \checkTABLErow\MR - \endTABLErow\TABLEmidrow00} - -\def\TableLR - {\ifTABLEgrayline \else - \ifnum\TABLEaction=\TABLErule - \writestatus\m!TABLE{change \string\LR\space into \string\FR/\string\SR}% - \fi - \fi - \checkTABLErow\LR - \endTABLErow\TABLElastrow\TABLErowzero\TABLErowfactor} - -%D \macros -%D {ifcheckTABLEcolums} -%D -%D -%D The next macros handle the actual row ending. This macro -%D also take care of space corrections due to table splitting -%D when \type{\MR} and collegues are used. When tracing is -%D enabled, the corrections as well as the values used to -%D determine the available space are shown (in color). By default -%D checking is off. - -\newif\ifcheckTABLEcolumns - -\let\beforeTABLEline\empty -\let\afterTABLEline \empty - -\def\doendTABLErow#1#2#3% - {\handleTABLEbreak#2#3% - \beforeTABLEline - \ifcase#1\relax - % unknown - \or - \endofTABLEline[blue][\SR->\SR]\TABLErowfactor\TABLErowfactor - \or - \endofTABLEline[red][\FR->\FR]\TABLErowfactor\TABLErowzero - \or - \ifnum\TABLEforce=\TABLEforcelastrow - \endofTABLEline[red][\MR->\LR]\TABLErowzero\TABLErowfactor - \else\ifnum\TABLEforce=\TABLEforcefirstrow - \endofTABLEline[red][\MR->\FR]\TABLErowfactor\TABLErowzero - \else - \endofTABLEline[green][\MR->\MR]\TABLErowzero\TABLErowzero - \fi\fi - \or - \endofTABLEline[red][\LR->\LR]\TABLErowzero\TABLErowfactor - \fi - \TABLEnoalign - {\setTABLEforce\TABLEunknown - \global\currentTABLEcolumn\zerocount}% - \afterTABLEline} - -\def\endTABLErow#1#2#3% - {\setTABLEaction#1% - \ifTABLEgrayline - \finishTABLErow - \else - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \doendTABLErow{#1}{#2}{#3}% - \else\ifcheckTABLEcolumns - \setTABLEerror\TABLEmissingcolumn - \handleTABLEerror - \else - \doendTABLErow{#1}{#2}{#3}% - \fi\fi - \fi} - -%D Handling \type{\AR} is postponed till the next row. The -%D check takes care of the first and mid rows, the chuck macro -%D |<|how about that name|>| handles the last row. - -\def\TableAR - {\ifTABLEgraydone - \globalletempty\checkTABLEautorow - \globalletempty\chuckTABLEautorow - \global\TABLEgraydonefalse - \TABLEendBCL - \else - \globallet\checkTABLEautorow\docheckTABLEautorow - \globallet\chuckTABLEautorow\dochuckTABLEautorow - \fi} - -\let\checkTABLEautorow\empty -\let\chuckTABLEautorow\empty - -\def\docheckTABLEautorow - {\globallet\checkTABLEautorow\empty - \ifnum\TABLEaction=\TABLErule \FR - \else\ifnum\TABLEaction=\TABLEunknown \FR - \else \MR - \fi\fi} - -\def\dochuckTABLEautorow - {\globalletempty\checkTABLEautorow - \globalletempty\chuckTABLEautorow - \ifnum\TABLEaction=\TABLErule \SR - \else\ifnum\TABLEaction=\TABLEunknown \SR - \else \LR - \fi\fi} - -%D When a table is split, we also add a tail and when present -%D we repeat the table head. - -\def\handleTABLEbreak#1#2% - {\globalletempty\beforeTABLEline - \gdef\afterTABLEline{\TABLEnoalign{\ifconditional\preventTABLEbreak\nobreak\else\goodbreak\fi}}} - -%D When tables are split, the spacing before and after a -%D horizontal rule is corrected according to what we expect. - -\def\endofTABLEline[#1][#2->#3]#4#5% - {\ifx#2#3\else - \writestatus\m!TABLE{\string#2\space changed into \string#3}% - \fi - \iftracetables - \bgroup - \tttf\space - \ifnum\TABLEerror=\TABLEunknown - \ifx#2#3\else\string#2->\fi - \else - ->% - \fi - \color[#1]{\string#3}% - \ifx\TABLEgraylineerror\empty - \space\TABLEgraylinestatus - \else - \space\TABLEgraylineerror - \fi - \egroup - \else\ifx\TABLEgraylineerror\empty \else - % \bgroup - % \tttf\space\TABLEgraylineerror - % \egroup - \fi\fi - \globalletempty\TABLEgraylinestatus - \globalletempty\TABLEgraylineerror - \expandafter\normalTABLElineformat#4#5\crcr % \crcr nodig ? - \TABLEnoalign{\nobreak\global\setTABLEactiontrue}} - -%D In order to prevent (as good as possible) alignment overflow -%D and therefore \TEX\ error messages, we check the maximum -%D number of columns. We keep track of the current column and -%D maximum column by means of two \COUNTERS. Keep in mind that -%D the number of \type{|}'s and \type{\VL}'s or alike is always -%D one more than the number of columns. - -\newcount\currentTABLEcolumn -\newcount\maxTABLEcolumn - -%D While defining this macro we change the \CATCODE\ of -%D \type{|}. When counting the bars, we use a non active -%D representation of the bar, simply because we cannot be sure -%D if the bar is active or not.\footnote{Normally it is, but -%D \TABLE\ changes the catcode when needed.} - -\bgroup - \catcode`\|=\@@other \gdef\@@otherbar {|} - \catcode`\"=\@@other \gdef\@@otherquote {"} - \catcode`\|=\@@active \gdef\@@useotherbar {\let|\@@otherbar} - \catcode`\"=\@@active \gdef\@@useotherquote{\let"\@@otherquote} -\egroup - -\bgroup \catcode`\|=\@@other - -\gdef\getTABLEnofcolumns#1% - {\bgroup - \cleanupfeatures % needed ! - \@@useotherbar - \@@useotherquote - \expanded{\defconvertedargument\noexpand\ascii{#1}}% - \@EA\doglobal\@EA\counttoken\@EA|\@EA\in\ascii\to\maxTABLEcolumn - \global\advance\maxTABLEcolumn \minusone - % in case of & counting, divide by 2 - \egroup} - -\egroup - -\def\!ttDoHalign - {\baselineskip \zeropoint - \lineskiplimit\zeropoint - \lineskip \zeropoint - \tabskip \zeropoint - % does not work in normal tex - % \expanded{\getTABLEnofcolumns{\the\!taPreamble}}% added - \halign \the\!taTableSpread \bgroup - \span\the\!taPreamble - \ifx \!tfRowOfWidths \empty \else \!tfRowOfWidths \cr \fi} - -%D \startitemize[3*ruim] -%D \sym{\type{\VL}} a vertical line -%D \sym{\type{\VC}} a vertical colored line -%D \sym{\type{\HL}} a horizontal line -%D \sym{\type{\HC}} a horizontal colored line -%D \stopitemize - -% \def\defineTABLErules -% {\let\VL\TableVL -% \let\VC\TableVC -% \let\HL\TableHL -% \let\HC\TableHC} - -\def\defineTABLErules - {\let\VL\TableVL - \let\VC\TableVC - \let\HL\TableHL - \let\HC\TableHC - \let\VS\TableVS - \let\VD\TableVD - \let\VT\TableVT - \let\VN\TableVN} - -\def\TableVL - {\checkTABLEautorow - \nextTABLEgrayline - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \setTABLEerror\TABLEmissingrow - \handleTABLEerror - \else - \global\advance\currentTABLEcolumn \plusone - \expandafter\doTableVL - \fi} - -\def\doTableVL - {\futurelet\next\dodoTableVL} - -\def\dodoTableVL - {\docomplexorsimpleTable\complexTableVL\simpleTableVL} - -\def\complexTableVL[#1]% - {\scratchcounter=0#1% - \multiply\scratchcounter \@@tiVLwidth - \setxvalue{wVL\the\currentTABLEcolumn}{\the\scratchcounter}% - \simpleTableVL} - -\def\simpleTableVL - {\doifundefined{wVL\the\currentTABLEcolumn}% - {\setgvalue{wVL\the\currentTABLEcolumn}{\@@tiVLwidth}}% - \gdef\TABLEbeforebar - {\getvalue{bVL\the\currentTABLEcolumn}% - \letgvalueempty{bVL\the\currentTABLEcolumn}}% - \gdef\TABLEafterbar - {\getvalue{eVL\the\currentTABLEcolumn}% - \letgvalueempty{eVL\the\currentTABLEcolumn}}% - \edef\@@tiVLwidth{\getvalue{wVL\the\currentTABLEcolumn}}% - \expanded{\normalTABLEcomplexbar\@@tiVLwidth\space}}% \relax breaks \use - -% \starttable[|||] -% \HL -% \VL test \VS test \VL \FR -% \VL test \VD test \VL \MR -% \VL test \VT test \VL \LR -% \HL -% \stoptable - -\def\TableVS {\VN1} -\def\TableVD {\VN2} -\def\TableVT {\VN3} -\def\TableVN#1{\gdef\@VLn{#1}\VL} - -\def\resetVLvalues - {\dostepwiserecurse\zerocount\maxTABLEcolumn\plusone - {\setgvalue{wVL\recurselevel}{\@@tiVLwidth}% - \letgvalueempty{bVL\recurselevel}% - \letgvalueempty{eVL\recurselevel}}% - \global\currentTABLEcolumn\zerocount} - -\def\TableVC - {\checkTABLEautorow - \nextTABLEgrayline - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \setTABLEerror\TABLEmissingrow - \handleTABLEerror - \else - \global\advance\currentTABLEcolumn \plusone - \expandafter\doTableVC - \fi} - -\def\doTableVC - {\futurelet\next\dodoTableVC} - -\def\dodoTableVC - {\docomplexorsimpleTable\complexTableVC\simpleTableVC} - -\def\complexTableVC[#1]% - {\global\setvalue{bVC\the\currentTABLEcolumn}{\localstartcolor[#1]}% - \global\setvalue{eVC\the\currentTABLEcolumn}{\localstopcolor}% - \simpleTableVC} - -\def\simpleTableVC - {\global\setvalue{bVL\the\currentTABLEcolumn}% - {\getvalue{bVC\the\currentTABLEcolumn}}% - \global\setvalue{eVL\the\currentTABLEcolumn}% - {\getvalue{eVC\the\currentTABLEcolumn}}% - \doTableVL} - -\def\TableHL - {\ifnum\currentTABLEcolumn>\maxTABLEcolumn - \chuckTABLEautorow - \else\ifnum\currentTABLEcolumn=\zerocount - %\chuckTABLEautorow - \TABLEnoalign - {\globalletempty\checkTABLEautorow - \globalletempty\chuckTABLEautorow}% - \else - \setTABLEerror\TABLEmissingcolumn - \handleTABLEerror - \fi\fi - \complexorsimpleTable{HL}} - -\def\complexTableHL[#1]% - {\TABLEnoalign - {\scratchcounter0#1% - \multiply\scratchcounter \@@tiHLheight - \edef\@@tiHLheight{\the\scratchcounter}% - \simpleTableHL}} - -\def\simpleTableHL - {\TABLEnoalign - {\nobreak - \ifnum\TABLEaction=\TABLErule - \writestatus\m!TABLE{skipping \string\HL}% \statusmessage - \else - \ifnum\TABLEaction=\TABLEmidrow - \writestatus\m!TABLE{change \string\MR\space into \string\LR/\string\SR}% - \else\ifnum\TABLEaction=\TABLEfirstrow - \writestatus\m!TABLE{change \string\MR\space into \string\SR}% - \fi\fi - \startHLcommand - \expandafter\normalTABLEfullrule\@@tiHLheight - \stopHLcommand - \globalletempty\startHLcommand - \globalletempty\stopHLcommand - \accountTABLElinewidth - \fi - \setTABLEaction\TABLErule - \nobreak}} - -\let\startHLcommand\empty -\let\stopHLcommand \empty - -\def\TableHC - {\complexorsimpleTable{HC}} - -\def\complexTableHC[#1]% - {\TABLEnoalign - {\gdef\startHCcommand{\localstartcolor[#1]}% - \gdef\stopHCcommand {\localstopcolor}}% - \simpleTableHC} - -\def\simpleTableHC - {\TABLEnoalign - {\globallet\startHLcommand\startHCcommand - \globallet\stopHLcommand \stopHCcommand}% - \HL} - -%D \startitemize[3*ruim] -%D \sym{\type{\NL}} a vertical skip -%D \sym{\type{\NR}} goto the next row -%D \sym{\type{\NC}} goto the next column -%D \sym{\type{\FC}} a first column -%D \sym{\type{\MC}} a mid column -%D \sym{\type{\LC}} a last column -%D \stopitemize - -% n+1 uitleggen - -\def\defineTABLEsteps - {\let\NL\TableNL - \let\NR\TableNR - \let\NC\TableNC - \let\FC\TableNC - \let\MC\TableNC - \let\LC\TableNC} - -\def\TableNL - {\complexorsimpleTable{NL}} - -\def\complexTableNL[#1]% - {\TABLEnoalign - {\edef\@@tiNL{#1}% - \simpleTableNL}}% - -\def\simpleTableNL - {\TABLEnoalign - {\nobreak - \setbox0\vbox{\blank[\@@tiNL]}% - \vskip\ht0 - \nobreak}} - -\def\TableNR - {\ifnum\currentTABLEcolumn>\maxTABLEcolumn - \global\currentTABLEcolumn\zerocount - \normalTABLElineending - \else - \setTABLEerror\TABLEmissingcolumn - \handleTABLEerror - \fi - \TABLEnoalign - {\nobreak - \setTABLEaction\TABLEunknown}} - -\def\TableNC - {\checkTABLEautorow - \nextTABLEgrayline - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \setTABLEerror\TABLEmissingrow - \handleTABLEerror - \else - \global\advance\currentTABLEcolumn \plusone - \normalTABLEquote - \fi} - -% \bgroup -% \catcode`\|=\@@active -% \catcode`\"=\@@active -% \gdef\redefinetablebarandquote -% {\def|{\VL}% % \normalTABLEsimplebar -% \def\|##1{\VL[##1]}% % \normalTABLEcomplexbar -% \def"{\NC}} % \normalTABLEquote -% \egroup - -\let\redefinetablebarandquote\relax - -%D \startitemize[3*ruim] -%D \sym{\type{\DL}} -%D \sym{\type{\DV}} (\type{\VD}) -%D \sym{\type{\DC}} -%D \sym{\type{\DR}} -%D \stopitemize - -\newif\ifTABLEdivision - -% \def\defineTABLEdivisions -% {\global\TABLEdivisionfalse % in start -% \let\DL\TableDL -% \let\DC\TableDC -% \let\DV\TableDV -% \let\VD\TableDV -% \let\DR\TableDR} - -\def\defineTABLEdivisions - {\global\TABLEdivisionfalse % in start - \let\DL\TableDL - \let\DC\TableDC - \let\DV\TableDV - \let\DR\TableDR} - -\def\checkTABLEdivision - {\ifTABLEdivision \else - \chuckTABLEautorow - \global\currentTABLEcolumn\zerocount - \global\TABLEdivisiontrue - \fi} - -\def\TableDL - {\checkTABLEdivision - \complexorsimpleTable{DL}} - -\def\simpleTableDL - {\complexTableDL[1]} - -\def\complexTableDL[#1]% - {\ifnum\TABLEaction=\TABLErule - \writestatus\m!TABLE{skipping \string\DL}% - \else - \ifnum\TABLEaction=\TABLEmidrow - \writestatus\m!TABLE{change \string\MR\space into \string\LR/\string\SR}% - \else\ifnum\TABLEaction=\TABLEfirstrow - \writestatus\m!TABLE{change \string\MR\space into \string\SR}% - \fi\fi - \setTABLEaction=\TABLEunknown - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \setTABLEerror\TABLEmissingrow - \handleTABLEerror - \fi - %\startHLcommand - \ifnum#1=\plusone - \global\advance\currentTABLEcolumn \plustwo - \let\next\normalTABLEsinglerule - \else - \ifnum#1<\maxTABLEcolumn - \global\advance\currentTABLEcolumn \plusone - \def\next{\normalTABLEmultirule{#1}}% - \else - \setTABLEerror\TABLEdivisionoverflow - \let\next\handleTABLEerror - \fi - \fi - \next - %\stopHLcommand - %\globalletempty\startHLcommand - %\globalletempty\stopHLcommand - \fi} - -\def\TableDV - {\TableDCV\normalTABLEsimplebar} - -\def\TableDC - {\TableDCV\normalTABLEquote} - -\def\TableDCV#1% - {\checkTABLEdivision - \checkTABLEautorow - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - \setTABLEerror\TABLEmissingrow - \handleTABLEerror - \else - \global\advance\currentTABLEcolumn \plusone - #1% - \fi} - -\def\TableDR - {\ifnum\currentTABLEcolumn<\maxTABLEcolumn % silent recovery - %\setTABLEerror\TABLEmissingcolumn % some day warning - %\handleTABLEerror - \finishTABLErow - \else - \global\currentTABLEcolumn\zerocount % nog check - \normalTABLElineending - \fi - \TABLEnoalign - {\nobreak - \global\TABLEdivisionfalse - \accountTABLElinewidth % temporary solution - \setTABLEaction\TABLErule}} - -\def\accountTABLElinewidth - {\scratchdimen\LineThicknessUnit} - -%D \startitemize[3*ruim] -%D \sym{\type{\BC}} -%D \sym{\type{\BR}} -%D \sym{\type{\BACKGROUND}} -%D \sym{\type{\CL}} -%D \sym{\type{\RL}} -%D \sym{\type{\BL}} -%D \sym{\type{\RASTER}} -%D \sym{\type{\COLOR}} -%D \stopitemize - -% definieer: \BC \BL -% herhaal: \BR -% definieer: \CL \RL (eerste \CL[green] = hele row! / \CL[1,green]) -% dus: \CL en \RL mix tussen \HL en \BL - -\def\defineTABLEbackgrounds - {\let\BC \TableBC - \let\BL \TableBL - \let\BR \TableBR - \let\BACKGROUND\TableBR - \let\CL \TableCL - \let\RL \TableRL - \let\COLOR \TableCOLOR - \let\RASTER \TableRASTER - \globallet\lastTABLEc\@@tibackgroundcolor - \globallet\lastTABLEr\@@tibackgroundscreen - \doifinsetelse\@@tibackground{c,color} % \v!color - {\global\chardef\TABLEcr\plusone} - {\global\chardef\TABLEcr\plustwo}} - -\def\TableBC - {\ifTABLEgrayline - \normalTABLEquote - \else - \TABLEnoalign\bgroup - \globallet\nextTABLEgrayline\executeTABLEgrayline - \globalletempty\TABLEgrayline % new - \let\BL\doTableBL - \let\BC\doTableBC - \expandafter\doTableBC - \fi} - -\def\doTableBC - {\addtoTABLEgrayline{\BC}% - \gobbleTableBCL} - -\def\TableBL - {\TABLEnoalign\bgroup - \globallet\nextTABLEgrayline\executeTABLEgrayline - \globalletempty\TABLEgrayline % new - \let\BL\doTableBL - \let\CL\doTableCL - \let\RL\doTableRL - \let\BC\doTableBC - \doTableBL} - -\def\doTableBL - {\complexorsimpleTable{BL}} - -\def\simpleTableBL - {\complexTableBL[,]} - -\def\complexTableBL[#1]% - {\analyzeTABLEcr[#1]% - \handleTABLEcr} - -\def\TableBR#1% - {\TABLEnoalign - {\globallet\nextTABLEgrayline\executeTABLEgrayline - \checkTABLEgrayline#1\BR - \global\TABLEgraylinetrue}} - -\def\analyzeTABLEcr[#1]% - {\doanalyzeTABLEcr[#1,,]} - -\def\doanalyzeTABLEcr[#1,#2,#3]% - {\doifnumberelse{#1x} % Is the x still needed here? - {\dodoanalyzeTABLEcr[#1,#2,#3]} - {\dodoanalyzeTABLEcr[1,#1,#2]}} - -\def\dodoanalyzeTABLEcr[#1,#2,#3]% - {\global\chardef\TABLEn#1\relax - \processaction - [#2] - [ c=>\global\chardef\TABLEcr1,% - color=>\global\chardef\TABLEcr1,% - r=>\global\chardef\TABLEcr2,% - raster=>\global\chardef\TABLEcr2]% - \ifcase\TABLEcr \or - \doifsomething{#3}{\xdef\lastTABLEc{#3}}% - \or - \doifsomething{#3}{\xdef\lastTABLEr{#3}}% - \fi} - -\def\handleTABLEcr - {\relax % else funny side effect - \ifcase\TABLEcr - % Can't happen! - \or - \addtoTABLEgrayline{\complexTableCOLOR[\the\TABLEn,\lastTABLEc]}% - \else - \addtoTABLEgrayline{\complexTableRASTER[\the\TABLEn,\lastTABLEr]}% - \fi - \gobbleTableBCL} - -\def\analyzeTABLEcrl#1[#2]% - {\doanalyzeTABLEcrl#1[#2,,]} - -\def\doanalyzeTABLEcrl#1[#2,#3,#4]% - {\doifnumberelse{#2x} % x ???????????????????? - {\dodoanalyzeTABLEcr[#2,#1,#3]} - {\dodoanalyzeTABLEcr[\ifTABLEgrayline1\else\maxTABLEcolumn\fi,#1,#2]}} - -\def\TableCL - {\TABLEnoalign\bgroup - \globallet\nextTABLEgrayline\executeTABLEgrayline - \globalletempty\TABLEgrayline % new - \let\BL\doTableBL - \let\CL\doTableCL - \let\RL\doTableRL - \let\BC\doTableBC - \doTableCL} - -\def\doTableCL - {\complexorsimpleTable{CL}} - -\def\simpleTableCL% nog eens \'e\'en lijn van maken - {\BL[\the\maxTABLEcolumn,c,\lastTABLEc]} - -\def\complexTableCL[#1]% - {\analyzeTABLEcrl{c}[#1]% - \handleTABLEcr} - -\def\TableRL - {\TABLEnoalign\bgroup - \globallet\nextTABLEgrayline\executeTABLEgrayline - \globalletempty\TABLEgrayline % new - \let\BL\doTableBL - \let\CL\doTableCL - \let\RL\doTableRL - \let\BC\doTableBC - \doTableRL} - -\def\doTableRL - {\complexorsimpleTable{RL}} - -\def\simpleTableRL - {\BL[\the\maxTABLEcolumn,r,\lastTABLEr]} - -\def\complexTableRL[#1]% - {\analyzeTABLEcrl{r}[#1]% - \handleTABLEcr} - -\def\checkTABLEgrayline#1#2% - {\!!doneatrue - \ifx#1\AR - \!!doneafalse - \else\ifx#1\SR\else\ifx#1\FR\else\ifx#1\MR\else\ifx#1\LR\else - \!!doneafalse - \fi\fi\fi\fi\fi - \if!!donea - \gdef\TABLEgraylinestatus - {[\string#1]}% - \gdef\TABLEendBCL - {#1}% - \else - \gdef\TABLEgraylineerror - {[\string#2\string#1->\string#2\string\SR]}% - \gdef\TABLEendBCL - {\SR}% - \fi} - -\def\endTABLErowGL#1#2#3% - {\ifcase#1\relax - % unknown - \or - \doPreTableGL\TABLErowfactor\TABLErowfactor - \or - \doPreTableGL\TABLErowfactor\TABLErowzero - \or - \ifnum\TABLEforce=\TABLEforcelastrow - \doPreTableGL\TABLErowzero\TABLErowfactor - \else\ifnum\TABLEforce=\TABLEforcefirstrow - \doPreTableGL\TABLErowfactor\TABLErowzero - \else - \doPreTableGL\TABLErowzero\TABLErowzero - \fi\fi - \or - \doPreTableGL\TABLErowzero\TABLErowfactor - \fi} - -\def\doPreTableGL#1#2% betere namen - {\xdef\OldLineThicknessFactor{\the\LineThicknessFactor}% - \xdef\OldLineThicknessUnit{\the\LineThicknessUnit}% - \global\LineThicknessFactor\plusone - \setbox0\hbox{\AugmentedTableStrut{#1}{#2}}% - \getboxheight\dimen0\of\box0\relax - \xdef\TABLEgraylineHeight{\the\dimen0}% - \global\LineThicknessUnit\TABLEgraylineHeight} - -\def\doPostTableGL - {\global\LineThicknessFactor\OldLineThicknessFactor - \global\LineThicknessUnit \OldLineThicknessUnit} - -% kan simpeler - -\def\docomplexTableCOLOR[#1]% - {\dodocomplexTableGL\localstartcolor \localstopcolor [#1,\lastTABLEc,,]} - -\gdef\docomplexTableRASTER[#1]% - {\dodocomplexTableGL\localstartraster\localstopraster[#1,\lastTABLEr,,]} - -\def\dodocomplexTableGL#1#2[#3,#4,#5,#6]% - {\doifelsenothing{#4}{#1[#5]}{#1[#4]}% - \doPreTableGL\TABLEendofrowheight\TABLEendofrowdepth - \ifnum#3=\plusone % else conflict with \omit in \= - \let\next\normalTABLEsinglerule - \else - \def\next{\normalTABLEmultirule{#3}}% - \fi - \next - \doPostTableGL - #2} - -\def\TableBACKGROUND - {\TableBR} - -\def\simpleTableRASTER #1{\docomplexTableRASTER[1]#1} -\def\complexTableRASTER[#1]{\docomplexTableRASTER[#1]} -\def\simpleTableCOLOR {\docomplexTableCOLOR [1]} -\def\complexTableCOLOR [#1]{\docomplexTableCOLOR [#1]} - -\def\TableRASTER{\complexorsimpleTable{RASTER}} -\def\TableCOLOR {\complexorsimpleTable{COLOR}} - -\def\addtoTABLEgrayline#1% - {\TABLEgraytoks\expandafter{\TABLEgrayline}% - \xdef\TABLEgrayline{\the\TABLEgraytoks\noexpand#1}} - -\def\setTableBCL#1#2% - {\ifx#1#2% - \gdef\TABLEgraylinestatus{[\string#1]}% - \gdef\TABLEendBCL{#1}% - \addtoTABLEgrayline{#1}% - \else - \gdef\TABLEgraylineerror{[\string#1->\string#2]}% - \gdef\TABLEendBCL{#2}% - \addtoTABLEgrayline{#2}% - \fi} - -\def\gobbleTableBCL#1% - {\ifx#1\BC \let\next\doTableBC \else - \ifx#1\BL \let\next\doTableBL \else - \ifx#1\SR \setTableBCL\SR\SR \let\next\egroup \else - \ifx#1\FR \setTableBCL\FR\FR \let\next\egroup \else - \ifx#1\MR \setTableBCL\MR\MR \let\next\egroup \else - \ifx#1\LR \setTableBCL\LR\LR \let\next\egroup \else - \setTableBCL #1\SR \let\next\egroup - \fi\fi\fi\fi\fi\fi - \next} - -\def\executeTABLEgrayline - {\TABLEnoalign - {\def\BC - {\advance\currentTABLEcolumn \plusone}% - \def\dodocomplexTableGL##1##2[##3,##4,##5,##6]% - {\BC\advance\currentTABLEcolumn ##3 }% - \let\endTABLErow\endTABLEgrayrow - \currentTABLEcolumn\zerocount - \TABLEgrayline\TABLEendBCL % determine n of columns and height - \advance\currentTABLEcolumn \minusone - \ifnum\currentTABLEcolumn>\maxTABLEcolumn - % error message too long line - \globalletempty\TABLEgrayline - \else - % \message{n of color columns: \the\currentTABLEcolumn}\wait - \global\TABLEgraylinetrue % vanaf hier nog checken - \fi - \global\currentTABLEcolumn\zerocount}% - \unskip\TABLEgrayline\TABLEendBCL - \TABLEnoalign - {\nobreak - \vskip-\TABLEgraylineHeight - \nobreak - \global\setTABLEactiontrue - \global\currentTABLEcolumn\zerocount - \globalletempty\nextTABLEgrayline - \global\TABLEgraydonetrue - \global\TABLEgraylinefalse}} - -\def\endTABLEgrayrow#1#2#3% - {\ifcase#1\relax - \global\chardef\TABLEendofrowheight\TABLErowfactor - \global\chardef\TABLEendofrowdepth \TABLErowfactor - \or - \global\chardef\TABLEendofrowheight\TABLErowfactor - \global\chardef\TABLEendofrowdepth \TABLErowfactor - \or - \global\chardef\TABLEendofrowheight\TABLErowfactor - \global\chardef\TABLEendofrowdepth \TABLErowzero - \or - \ifnum\TABLEforce=\TABLEforcelastrow - \global\chardef\TABLEendofrowheight\TABLErowzero - \global\chardef\TABLEendofrowdepth \TABLErowfactor - \else\ifnum\TABLEforce=\TABLEforcefirstrow - \global\chardef\TABLEendofrowheight\TABLErowfactor - \global\chardef\TABLEendofrowdepth \TABLErowzero - \else - \global\chardef\TABLEendofrowheight\TABLErowzero - \global\chardef\TABLEendofrowdepth \TABLErowzero - \fi\fi - \or - \global\chardef\TABLEendofrowheight\TABLErowzero - \global\chardef\TABLEendofrowdepth \TABLErowfactor - \fi} - -\def\defineTABLEshorthands% - {\def\SPAN##1{\use{##1}}% - \def\TWO {\use2}% - \def\THREE {\use3}% - \def\FOUR {\use4}% - \def\FIVE {\use5}% - \def\SIX {\use6}% - \def\REF {\ReFormat}} - -\def\defineTABLEunits - {\processaction - [\@@tidistance] - [ \v!none=>\OpenUp00\def\LOW{\Lower6 }, - \v!small=>\OpenUp00\def\LOW{\Lower6 }, % == baseline - \v!medium=>\OpenUp11\def\LOW{\Lower7 }, - \v!big=>\OpenUp22\def\LOW{\Lower8 }]% - \doifelse\@@tidistance\v!none - {\chardef\TABLErowfactor\zerocount} - {\chardef\TABLErowfactor\plustwo }} - -\def\dohandlebar % here ? - {\ifmmode - \@EA\domathmodebar - \else\ifintable - \@EAEAEA\domathmodebar - \else - \@EAEAEA\dotextmodebar - \fi\fi} - -% De macro's t.b.v. instellingen. - -\def\setuptables - {\dosingleargument\dosetuptables} - -\def\dosetuptables[#1]% - {\getparameters[\??ti][#1]% - \processaction - [\@@tialign] - [ \v!right=>\def\TABLEparalignment{\raggedright}, - \v!left=>\def\TABLEparalignment{\raggedleft}, - \v!middle=>\def\TABLEparalignment{\raggedcenter}, - \s!default=>\def\TABLEparalignment{\notragged}, - \s!unknown=>\def\TABLEparalignment{\notragged}]% - \assignalfadimension\@@tiVL\@@tiVLwidth 246% - \assignalfadimension\@@tiHL\@@tiHLheight246} - -\def\localTABLEsetup - {\@@ticommands\relax - \expanded{\switchtobodyfont[\@@tibodyfont]}% - \StrutHeightFactor 8 - \StrutDepthFactor 4 - \LineThicknessFactor4 - \NormalTLTU {.1pt}% - \NormalTSU {\normalbaselineskip\divide\StrutUnit 12 }% - \NormalTableUnits} - -%D And then I wrote the tabulate environment. That -%D alternative supports setting the rule thickness and color, -%D so here is the table alternative. - -\let\startglobalTABLEcolor\empty -\let\stopglobalTABLEcolor \empty - -\def\localTABLEsetup - {\@@ticommands\relax - % bodyfont - \expanded{\switchtobodyfont[\@@tibodyfont]}% - % linecolor - \doifsomething\@@tirulecolor - {\def\startglobalTABLEcolor{\localstartcolor[\@@tirulecolor]}% - \def\stopglobalTABLEcolor {\localstopcolor}}% - % linethickness - \LineThicknessFactor4 - \scratchdimen\@@tirulethickness - \divide\scratchdimen \LineThicknessFactor - \expanded{\NormalTLTU{\the\scratchdimen}}% - % spacing, was depth=4 height=8 (counters, sigh, now macros) - \doifelse\@@tiheight\v!strut - {\let\StrutHeightFactor\@@itheight} - {\let\StrutHeightFactor\@@tiheight}% - \doifelse\@@tidepth\v!strut - {\let\StrutDepthFactor\@@itdepth} - {\let\StrutDepthFactor\@@tidepth}% - \scratchdimen\StrutHeightFactor\points \multiply\scratchdimen 10% - \edef\StrutHeightFactor{\withoutpt\the\scratchdimen}% - \scratchdimen\StrutDepthFactor \points \multiply\scratchdimen 10% - \edef\StrutDepthFactor{\withoutpt\the\scratchdimen}% - % units - \NormalTSU{\normalbaselineskip\divide\StrutUnit 12 }% - \NormalTableUnits} - -\def\OpenUp#1#2% - {\scratchdimen\StrutHeightFactor \points \advance\scratchdimen #1\points - \edef\StrutHeightFactor{\withoutpt\the\scratchdimen}% - \scratchdimen\StrutDepthFactor \points \advance\scratchdimen #2\points - \edef\StrutDepthFactor{\withoutpt\the\scratchdimen}} - -%D As one can see, we didn't only add color, but also more -%D control over spacing. -%D -%D \startbuffer[a] -%D \starttable[|c|] -%D \HL -%D \VL \strut test \VL \FR -%D \VL \strut test \VL \MR -%D \VL \strut test \VL \MR -%D \VL \strut test \VL \LR -%D \HL -%D \stoptable -%D \stopbuffer -%D -%D \startbuffer[b] -%D \starttabulate[|c|] -%D \HL -%D \NC test \NC \NR -%D \NC test \NC \NR -%D \NC test \NC \NR -%D \NC test \NC \NR -%D \HL -%D \stoptabulate -%D \stopbuffer -%D -%D In the next example, the first table is defined as: -%D -%D \typebuffer[a] -%D -%D and the second one as: -%D -%D \typebuffer[b] -%D -%D The first table is typeset using the default height and -%D depth factors .8 and .4. The second table has both factors -%D set to \type {strut}, and the third table shows what -%D happens when we set the values to zero. The rightmost table -%D is typeset using the tabulate environment. -%D -%D \startcombination[4*1] -%D {$\vcenter{\getbuffer[a]}$} -%D {\hbox{h=.8 d=.4}} -%D {\setuptables[height=strut,depth=strut]$\vcenter{\getbuffer[a]}$} -%D {\hbox{h=d=\type{strut}}} -%D {\setuptables[height=0,depth=0]$\vcenter{\getbuffer[a]}$} -%D {\hbox{h=d=0}} -%D {$\vcenter{\getbuffer[b]}$} -%D {\hbox{tabulate}} -%D \stopcombination - -\setuptables - [HL=\v!medium, - VL=\v!medium, - NL=\v!small, - \c!frame=, - \c!align=\v!right, - \c!depth=.40, % \v!strut - \c!height=.80, % \v!strut - \c!rulethickness=\linewidth, - \c!rulecolor=, - \c!distance=\v!medium, - \c!bodyfont=\the\bodyfontsize, - \c!commands=, - \c!background=\v!screen, - \c!backgroundscreen=\@@rsscreen, - \c!backgroundcolor=, - \c!split=\v!auto] - -\def\ifintabel{\ifintable} % upward compatible - -\protect \endinput diff --git a/tex/context/base/core-tbl.tex b/tex/context/base/core-tbl.tex deleted file mode 100644 index a5d5a37da..000000000 --- a/tex/context/base/core-tbl.tex +++ /dev/null @@ -1,1436 +0,0 @@ -%D \module -%D [ file=core-tbl, -%D version=1998.11.03, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Text Flow Tabulation, -%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 / Tabulation} - -% \processbetween gebruiken in head/tail macros - -\unprotect - -% WATCH OUT: don't change this model else trialtypesetting -% compatibility problems - -% watch out, cells expand pretty late on a per row basis - -% |p2|p3| 2:3 -% spanning - -% Be careful with changing the hsize calculation in p mode; -% the following code works quite well: -% -% \setupfield [line][location=low,height=1.2\lineheight,width=\hsize] -% \definefield [test] [line] [line] [] -% -% \starttabulate[|l|p|] -% \NC test \NC \field [test] \NC \NR -% \stoptabulate - -% In-text tabbing environment -% -% \starttabulate[| separated template] % eg [|l|p|] or [|l|p|p|] -% \NC ... \NC ... \NC\NR -% \stoptabulate -% -% with: two pass auto width calculation when no p-width -% specified, even with multiple p's, see examples. - -% TaBlE compatible specifications: -% -% l align column/paragraph left -% r align column/paragraph right -% c align column/paragraph center -% p p(dimen) of automatisch als alleen p -% w column width -% f font#1 -% B bold -% I italic -% S slanted -% T type -% R roman -% m math -% M display math -% h hook (inner level or par lines) -% b before (may be command#1) -% a after -% i i skip left of column -% j i skip right of column -% k i skip around column - -% s setups - -% g g{char} align at char -% . align at . -% , align at , - -% Still to be done - -% N math numbers (best hook into existing digits mechanism) -% n numbers (best hook into existing digits mechanism) -% Q math numbers (best hook into existing digits mechanism) -% q numbers (best hook into existing digits mechanism) -% ~ \hskip.5em -% | check - -% nesting - -% 10 evt auto stack; dan wel andere signal dan void nodig - -% present but not yet 100% ok -% -% \FL top hrule -% \ML mid hrule (with auto split) -% \LL bottom hrule -% \HL - -% \VL as soon as needed -% color as soon as needed - -% \EQ \RQ \HQ equal (raw, hook) -% \NC \RC \HC normal (raw, hook) -% -% \NR - -% \HR : rule with lineheight - -% \autotabulaterule : with lineheight, not first/last -% \autotabulateline : spaced, not first/last -% \tabulaterule : with lineheight -% \tabulateline : spaced - -% tricky: align scans ahead, over # and expands ones before -% while doing - -% new: -% -% \starttabulate[|cg{.}|cg{,}|cg{,}|] -% \NC period \NC comma \NC comma \NC\NR -% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR -% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR -% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR -% \NG 10 \NG 10 \NG 0,00 \NC\NR -% \stoptabulate -% -% \starttabulate[|c.|c,|c,|] -% \NC period \NC comma \NC comma \NC\NR -% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR -% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR -% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR -% \NG 10 \NG 10 \NG 0,00 \NC\NR -% \stoptabulate - -% nice demo (for BG) -% -% \starttabulate[|r|b{$\star$}|ra{\percent}|b{=}|r|] -% \NC 500 \NC \NC 60 \NC \NC 300 \NC \NR -% \NC 500 \NC \NC 55 \NC \NC 275 \NC \NR -% \NC 500 \NC \NC 50 \NC \NC 250 \NC \NR -% \NC 500 \NC \NC 45 \NC \NC 225 \NC \NR -% \NC 500 \NC \NC 40 \NC \NC 200 \NC \NR -% \NC 500 \NC \NC 35 \NC \NC 175 \NC \NR -% \NC 500 \NC \NC 30 \NC \NC 150 \NC \NR -% \NC 500 \NC \NC 25 \NC \NC 125 \NC \NR -% \NC 500 \NC \NC 20 \NC \NC 100 \NC \NR -% \stoptabulate - -\newtoks \tabulatepreamble -\newtoks \tabulatebefore -\newtoks \tabulateafter -\newtoks \tabulatebmath -\newtoks \tabulateemath -\newtoks \tabulatefont -\newtoks \tabulatesettings -\newtoks \tabulatedummy - -\newcount \nofautotabulate -\newcount \tabulatecolumns -\newcount \tabulatecolumn - -\newcount \tabulateminplines -\newcount \tabulatemaxplines - -\newif \ifautotabulate -\newif \ifsplittabulate \splittabulatetrue - -\newif \ifhandletabulatepbreak \handletabulatepbreaktrue -\newif \iftabulatenopbreak \tabulatenopbreakfalse - -\newif \iftabulateequal -\newif \iftracetabulate -\newif \ifframedtabulate - -\newdimen \tabulatepwidth -\newdimen \tabulatewidth -\newdimen \tabulateunit -\newdimen \tabulatemaxpheight - -\newbox \tabulatebox - -% [|lg{.}|] => \NG 12.34 \NC - -\gdef\handletabulatecharalign#1 % space delimited ! - {\edef\alignmentclass{\the\tabulatecolumn}% - \edef\alignmentcharacter{\getvalue{\@@tabalign@@\the\tabulatecolumn}}% - \ifcase\tabulatepass\or - \setfirstpasscharacteralign\checkalignment{#1}% - \fi % force hsize - \setsecondpasscharacteralign\checkalignment{#1}} - -\def\noftabcolumns{16} - -\def\@@tabbox@@ {@@tabbox@} -\def\@@tabhook@@ {@@tabhook@} -\def\@@tabalign@@ {@@tabalign@} -\def\@@tabsetups@@{@@tabsetups@} - -% \dorecurse\noftabcolumns % quick and dirty stack -% {\@EA\newbox\csname\@@tabbox@@\recurselevel\endcsname} - -\def\tablebox#1% - {\csname\@@tabbox@@\number#1\endcsname} - -% \def\checktablebox#1% -% {\ifundefinedelse{\@@tabbox@@\number#1}% -% \expandafter\newbox\csname\@@tabbox@@\number#1\endcsname -% \fi} - -\def\initializetablebox#1% also used elsewhere - {\ifcsname\@@tabbox@@\number#1\endcsname - \global\setbox\csname\@@tabbox@@\number#1\endcsname\box\voidb@x - \else - \expandafter\newbox\csname\@@tabbox@@\number#1\endcsname - \fi} - -% \def\initializetableboxes#1% hm, not that efficient, best make a simple dedicated tail recurser -% {\dorecurse#1{\initializetablebox\recurselevel}} - -\def\initializetableboxes#1% - {\scratchcounter#1\relax - \doinitializetableboxes} - -\def\doinitializetableboxes - {\ifnum\scratchcounter>\zerocount - \initializetablebox\scratchcounter - \advance\scratchcounter\minusone - \expandafter\doinitializetableboxes - \fi} - -\initializetableboxes\noftabcolumns - -\def\dotabulatenobreak - {\noalign - {\nobreak - \iftracetabulate - \red\hrule\!!height.5\linewidth\!!depth.5\linewidth - \par - \kern-\linewidth - \nobreak - \fi}} - -\let\notabulatehook\empty - -\def\checktabulatehook - {\ifnum\tabulatetype<\plustwo - \global\let\tabulatehook\notabulatehook - \else - \global\let\tabulatehook\dotabulatehook - \fi} - -\def\checktabulatesetups - {\getvalue{\@@tabsetups@@\the\tabulatecolumn}} - -\let\pretabrule \donothing -\let\posttabrule\donothing - -\def\dodosettabulatepreamble#1#2% - {\ifzeropt\tabulatewidth - \ifcase\tabulatemodus\relax - \let\preamblebox\empty - \else - \def\preamblebox{\autotabulatetrue}% - \fi - \else - \ifcase\tabulatemodus\relax - \edef\preamblebox{\hbox to \the\tabulatewidth}% - \else - \edef\preamblebox{\hsize\the\tabulatewidth}% - \fi - \fi - % - % less bytes - % - %\edef\preamblebox% - % {\ifcase\tabulatewidth - % \ifcase\tabulatemodus\relax\else\noexpand\autotabulatetrue\fi - % \els - % \ifcase\tabulatemodus\relax\hbox to\else\hsize\fi\the\tabulatewidth - % \fi}% - % - % 0 = NC column next EQ equal column - % 1 = RC column raw RQ equal column raw - % 2 = HC column hook HQ equal column hook - % some entries can be left out if we test for them being set - \@EA\appendtoks \@EA&\@EA\hskip\pretabskip\pretabrule##&\to\!!toksa - \appendtoks \ignorespaces\to\!!toksa - \@EA\appendtoks\@EA\global\@EA\tabulatecolumn\the\tabulatecolumns\relax\to\!!toksa - \appendtoks \checktabulatesetups\to\!!toksa - \appendtoks \checktabulatehook\to\!!toksa - \@EA\appendtoks \preamblebox\to\!!toksa - \appendtoks \bgroup\bbskip\bgroup#1\to\!!toksa - \appendtoks\ifnum\tabulatetype=\plusone \else \to\!!toksa - \@EA\appendtoks \the\tabulatebmath\to\!!toksa - \@EA\appendtoks \the\tabulatefont\to\!!toksa - \@EA\appendtoks \the\tabulatesettings\to\!!toksa - \@EA\appendtoks \the\tabulatebefore\to\!!toksa - \appendtoks\fi \to\!!toksa - \appendtoks \bgroup\ignorespaces\to\!!toksa - % - \appendtoks \tabulatehook##\to\!!toksa - % - %%\doifdefinedelse{\@@tabalign@@\tabulatecolumns} - %\doifdefinedelse{\@@tabalign@@\the\tabulatecolumns} - % {\appendtoks\handletabulatecharalign## \to\!!toksa} - % {\appendtoks\tabulatehook ##\to \!!toksa}% - % waarom kan ik hier geen \xx{##} geven, om een of - % andere reden passeert dan tex de hele regel (incl \NC's) - % als argument; elke delimiter <> space gaat trouwens fout - \appendtoks \unskip\unskip\ifmmode\else\endgraf\fi\egroup\to\!!toksa - \appendtoks\ifnum\tabulatetype=1 \else \to\!!toksa - \@EA\appendtoks \the\tabulateafter\to\!!toksa - \@EA\appendtoks \the\tabulateemath\to\!!toksa - \appendtoks\fi \to\!!toksa - \appendtoks #2\egroup\egroup\to\!!toksa - \@EA\appendtoks \@EA&\@EA\posttabrule\@EA\hskip\postabskip##\to\!!toksa - \appendtoks\NC\to\tabulatedummy - \let\bbskip\empty - \def\pretabskip{.5\tabulateunit}% - \let\postabskip\pretabskip - \let\gettabulateexit\dogettabulateexit - \tabulatewidth\zeropoint} - -% todo: we can speed up this module a bit -% -% \expanded{\!!toksa{\the\!!toksa -% &\hskip\pretabskip\noexpand\pretabrule####& -% \ignorespaces -% \global\tabulatecolumn\the\tabulatecolumns -% \noexpand\checktabulatesetups -% \noexpand\checktabulatehook -% \preamblebox -% \bgroup\noexpand\bbskip\bgroup\normalunexpanded{#1}% -% \noexpand\ifnum\tabulatetype=\plusone \noexpand\else -% \the\tabulatebmath -% \the\tabulatefont -% \the\tabulatesettings -% \the\tabulatebefore -% \noexpand\fi -% \bgroup\ignorespaces -% \noexpand\tabulatehook####% -% \unskip\unskip\noexpand\ifmmode\noexpand\else\endgraf\noexpand\fi\egroup -% \noexpand\ifnum\noexpand\tabulatetype=1 \noexpand\else -% \the\tabulateafter -% \the\tabulateemath -% \noexpand\fi -% \normalunexpanded{#2}\egroup\egroup -% &\noexpand\posttabrule\hskip\noexpand\postabskip####}}% - -\def\dosettabulatepreamble - {\ifx\next\relax - \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 - \else\ifx p\next \let\nextnext\gettabulateparagraph - \else\ifx s\next \let\nextnext\gettabulatesetups - \else\ifx w\next \let\nextnext\gettabulatewidth - \else\ifx f\next \let\nextnext\gettabulatefont - \else\ifx B\next \tabulatefont{\bf}% - \else\ifx I\next \tabulatefont{\it}% - \else\ifx S\next \tabulatefont{\sl}% - \else\ifx T\next \tabulatefont{\tt}% - \else\ifx R\next \tabulatefont{\rm}% - \else\ifx m\next \tabulatebmath{$}\tabulateemath{$}% - \else\ifx M\next \tabulatebmath{$\displaystyle}\tabulateemath{$}% - \else\ifx h\next \let\nextnext\gettabulatehook - \else\ifx b\next \let\nextnext\gettabulatebefore - \else\ifx a\next \let\nextnext\gettabulateafter - \else\ifx i\next \let\nextnext\gettabulatepreskip - \else\ifx j\next \let\nextnext\gettabulateposskip - \else\ifx k\next \let\nextnext\gettabulatepreposskip - \else\ifx X\next \let\nextnext\gettabulateexit % internal - \else\ifx e\next \appendtoks\global\tabulateequaltrue\to\tabulatesettings - \else\ifx ~\next \appendtoks\fixedspaces\to\tabulatesettings - \else\ifx g\next \let\nextnext\gettabulatealign - \else\ifx .\next \def\nextnext{\gettabulatealign.}% - \else\ifx ,\next \def\nextnext{\gettabulatealign,}% - \else \message{unknown preamble key [\meaning\next]}% - \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi - \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi - \fi - \nextnext} - -\def\dogettabulateexit - {\let\postabskip\!!zeropoint - \settabulatepreamble} - -\let\gettabulateexit\dogettabulateexit - -\def\gettabulatepreskip#1% - {\doifnumberelse{#1} - {\scratchdimen#1\tabulateunit\let\next\empty} - {\scratchdimen.5\tabulateunit\def\next{#1}}% - \edef\pretabskip{\the\scratchdimen}% - \@EA\settabulatepreamble\next} - -\def\gettabulateposskip#1% - {\doifnumberelse{#1} - {\scratchdimen#1\tabulateunit\let\next\empty} - {\scratchdimen.5\tabulateunit\def\next{#1}}% - \edef\postabskip{\the\scratchdimen}% - \let\gettabulateexit\settabulatepreamble - \@EA\settabulatepreamble\next} - -\def\gettabulatepreposskip#1% - {\doifnumberelse{#1} - {\scratchdimen#1\tabulateunit\let\next\empty} - {\scratchdimen.5\tabulateunit\def\next{#1}}% - \edef\pretabskip{\the\scratchdimen}% - \let\postabskip\pretabskip - \let\gettabulateexit\settabulatepreamble - \@EA\settabulatepreamble\next} - -\def\gettabulatesetups#1% - {\setvalue{\@@tabsetups@@\the\tabulatecolumns}{\setups[#1]}% - \settabulatepreamble} - -\def\gettabulatehook#1% - {\setvalue{\@@tabhook@@\the\tabulatecolumns}{#1}% - \settabulatepreamble} - -\def\gettabulatealign#1% - {\setvalue{\@@tabalign@@\the\tabulatecolumns}{#1}% - \settabulatepreamble} - -\def\gettabulatebefore#1% - {\tabulatebefore{#1}% - \settabulatepreamble} - -\def\gettabulateafter#1% - {\tabulateafter{#1}% - \settabulatepreamble} - -\def\gettabulatefont#1% - {\tabulatefont{#1}% - \settabulatepreamble} - -\def\gettabulatewidth - {\chardef\tabulatemodus\zerocount - \chardef\tabulatedimen\zerocount - \doifnextcharelse(\dogettabulatewidth\settabulatepreamble} - -\def\gettabulateparagraph - {\doifnextcharelse{(} - {\chardef\tabulatemodus\plusone - \chardef\tabulatedimen\plusone - \dogettabulatewidth} - {\chardef\tabulatemodus\plustwo - \chardef\tabulatedimen\zerocount - \settabulatepreamble}} - -% \def\dogettabulatewidth(#1)% -% {\tabulatewidth#1\relax -% \ifnum\tabulatedimen=\plusone -% \global\advance\tabulatepwidth\tabulatewidth -% \fi -% \settabulatepreamble} - -% \def\dogettabulatewidth(#1)% -% {\doifelse{#1}\v!passend -% {\chardef\tabulatemodus\plusthree} -% {\tabulatewidth#1\relax}% -% \ifnum\tabulatedimen=\plusone -% \global\advance\tabulatepwidth\tabulatewidth -% \fi -% \settabulatepreamble} - -% \startbuffer -% \toplinebox{\framed[width=3cm,height=2cm]{tufte}} -% \stopbuffer -% \starttabulate[|p(fixed)|p|] -% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR} -% \stoptabulate -% \starttabulate[|p(fit)|p|] -% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR} -% \stoptabulate - -\def\dogettabulatewidth(#1)% - {\processallactionsinset - [#1]% - [ \v!fit=>\chardef\tabulatemodus\plusthree, - \v!fixed=>\chardef\tabulatemodus\plusthree - \tabulatenopbreaktrue, - \s!unknown=>\tabulatewidth#1\relax]% - \ifnum\tabulatedimen=\plusone - \global\advance\tabulatepwidth\tabulatewidth - \fi - \settabulatepreamble} - -\def\settabulatepreamble - {\afterassignment\dosettabulatepreamble\let\next=} - -\def\tabulateraggedright {\ifnum\tabulatetype=\plusone \else\raggedright \fi} -\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} - -\bgroup \catcode`\|=\@@other - -\gdef\nexttabulate#1|% - {\chardef\tabulatealign\@@tabulatealign - \chardef\tabulatemodus\zerocount - \chardef\tabulatedimen\zerocount - \tabulatebefore \emptytoks - \tabulateafter \emptytoks - \tabulatebmath \emptytoks - \tabulateemath \emptytoks - \tabulatefont \emptytoks - \tabulatesettings\emptytoks - \global\advance\tabulatecolumns\plusone - \letvalue{\@@tabsetups@@\the\tabulatecolumns}\donothing - \settabulatepreamble#1\relax\relax % permits i without n - \ifcase\tabulatemodus\relax - \ifcase\tabulatealign\relax - \dodosettabulatepreamble\empty \tabulatehss \or - \dodosettabulatepreamble\empty \tabulatehss \or - \dodosettabulatepreamble\tabulatehss\empty \or - \dodosettabulatepreamble\tabulatehss\tabulatehss \fi - \or % fixed width - \ifcase\tabulatealign\relax - \dodosettabulatepreamble \bskip \eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedleft }\eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi - \or % auto width - \global\advance\nofautotabulate\plusone - \ifcase\tabulatealign\relax - \dodosettabulatepreamble \bskip \eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedleft }\eskip \or - \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi - \or % simple - \dodosettabulatepreamble \xbskip \xeskip - \fi - \futurelet\next\donexttabulate} - -\egroup - -\def\donexttabulate - {\ifx\next\relax\else - \expandafter\nexttabulate - \fi} - -\def\splitofftabulatebox - {\dontcomplain - \global\setbox\tabulatebox % % % global ? % % % - \vsplit\tablebox\tabulatecolumn to \lineheight - \setbox\tabulatebox\normalvbox - {\unvbox\tabulatebox}% - \setbox\tabulatebox\hbox to \wd\tabulatebox - {\hss\dotabulatehook{\box\tabulatebox}\hss}% - \ht\tabulatebox\strutht - \dp\tabulatebox\strutdp - \box\tabulatebox} - -\def\dotabulatehook {\getvalue{\@@tabhook@@ \the\tabulatecolumn}} -\def\dotabulatealign {\getvalue{\@@tabalign@@ \the\tabulatecolumn}} - -\def\resettabulatepheight - {\global\tabulateminplines\plusone - \getnoflines\tabulatemaxpheight - \global\tabulatemaxplines\noflines - \global\tabulatemaxpheight\zeropoint} - -\def\settabulatepheight - {\scratchdimen\ht\tablebox\tabulatecolumn\relax - \ifdim\scratchdimen>\tabulatemaxpheight - \global\tabulatemaxpheight\scratchdimen - \fi} - -\def\handletabulatepbreak - {\TABLEnoalign - {\ifhandletabulatepbreak - \iftabulatenopbreak - \dotabulatenobreak - \else\ifnum\tabulatemaxplines>\plusone - \ifnum\tabulateminplines=\plusone - \dotabulatenobreak - \fi - \global\advance\tabulateminplines\plusone - \ifnum\tabulateminplines=\tabulatemaxplines\relax - \dotabulatenobreak - \fi - \fi \fi - \fi}} - -%D \startbuffer -%D \starttabulate[|c|p|p|] -%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR -%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR -%D \NC 2 \NC \thinrules[n=3] \NC \thinrules[n=3] \NC\NR -%D \NC 3 \NC oh yes \NC simply no \NC\NR -%D \NC 4 \NC very true \NC as false as can be \NC\NR -%D \NC 5 \NC \thinrules[n=5] \NC \thinrules[n=5] \NC\NR -%D \NC 6 \NC \thinrules[n=3] \NC \thinrules[n=4] \NC\NR -%D \stoptabulate -%D \stopbuffer -%D -%D \typebuffer {\tracetabulatetrue\getbuffer} -%D -%D \startbuffer -%D \starttabulate[|c|p|p|] -%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR -%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR -%D \NC 2 \NC oh yes \NC simply no \NC\NR -%D \NC 3 \NC very true \NC as false as can be \NC\NR -%D \NC 4 \NC the whole truth \NC but the truth \NC\NR -%D \stoptabulate -%D \stopbuffer -%D -%D \typebuffer {\tracetabulatetrue\getbuffer} - -% \definetabulate -% \redefinetabulate -% \starttabulate[preamble] -% \starttabulate -> \starttabulate[|l|p|] - -\bgroup \catcode`\|=\@@other - -\gdef\definetabulate - {\dotripleempty\dodefinetabulate} - -\gdef\dodefinetabulate[#1][#2][#3]% - {\ifthirdargument - \doifundefined{\??tt#1::\c!unit} - {\copyparameters - [\??tt#1::][\??tt\v!tabulate::]% - [\c!frame,\c!distance,\c!unit,\c!before,\c!bodyfont,\c!after, - \c!inner,\c!indenting,\c!margin,\c!align,\c!header,\c!title, - \c!rulecolor,\c!rulethickness,\c!split,EQ]}% - \copyparameters - [\??tt#1::#2][\??tt#1::]% - [\c!unit,\c!distance,\c!before,\c!bodyfont,\c!after, - \c!inner,\c!indenting,\c!frame,\c!split,\c!header,\c!title, - \c!margin,\c!align,\c!rulecolor,\c!rulethickness,EQ]% - \setvalue{\e!start#1::#2}{\dofinalstarttabulate[#1][#2][#3]}% - \setvalue{\e!start#1}{\bgroup\dosubstarttabulate[#1]}% - \letvalue{\??tt#1-\v!header}\empty - \letvalue{\??tt#1-\v!footer }\empty - \else\ifsecondargument - \definetabulate[#1][][#2]% - \else - \definetabulate[#1][][|l|p|]% - \fi\fi} - -\egroup - -\let\tabulateheadcontent\empty -\let\tabulatetailcontent\empty - -\newconditional\tabulatesomeamble - -\def\checkfulltabulatecontent % - needed, else confusion with \c!header - {\ifundefined{\??tt\currenttabulate-\v!header}% - \let\tabulateheadcontent\empty - \else - \def\tabulateheadcontent - {\TABLEnoalign{\global\settrue\tabulatesomeamble}% - \csname\??tt\currenttabulate-\v!header\endcsname - \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% - \fi - \ifundefined{\??tt\currenttabulate-\v!footer}% - \let\tabulatetailcontent\empty - \else - \def\tabulatetailcontent - {\TABLEnoalign{\global\settrue\tabulatesomeamble}% - \csname\??tt\currenttabulate-\v!footer\endcsname - \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% - \fi} - -% \def\fulltabulatecontent -% {\tabulateheadcontent -% \tabulatecontent -% \tabulatetailcontent} - -\def\fulltabulatecontent - {\tabulateheadcontent - \tabulatecontent - \tabulatetailcontent - \removefunnytabulateline} - -\def\removefunnytabulateline - {\ifhmode - \strut\crcr - \TABLEnoalign{\kern-\lineheight}% - \fi} - -\setvalue{\e!start\v!tabulatehead}% - {\dosingleempty\dostartstarttabulatehead} - -\def\dostartstarttabulatehead[#1]% - {\processcontent{\e!stop\v!tabulatehead}\next - {\letvalue{\??tt\iffirstargument#1\else\v!tabulate\fi::-\v!header}\next}} - -\setvalue{\e!start\v!tabulatetail}% - {\dosingleempty\dostartstarttabulatetail} - -\def\dostartstarttabulatetail[#1]% - {\processcontent{\e!stop\v!tabulatetail}\next - {\letvalue{\??tt\iffirstargument#1\else\v!tabulate\fi::-\v!footer}\next}} - -\def\dosubstarttabulate - {\dodoubleempty\dodosubstarttabulate} - -\def\dodosubstarttabulate[#1][#2]% - {\getvalue{\e!start#1::\ifundefined{\e!start#1::#2}\else#2\fi}} - -\setvalue{\e!start\v!tabulate}% - {\bgroup\dodoubleempty\donormalstarttabulate} - -\bgroup - -\gdef\donormalstarttabulate[#1][#2]% - {\ifsecondargument - \getparameters[\??tt\v!tabulate::][#2]% - \fi - \iffirstargument - \def\next{\dofinalstarttabulate[\v!tabulate][][#1]}% - \else - \def\next{\dofinalstarttabulate[\v!tabulate][][|l|p|]}% - \fi - \next} - -\egroup - -% The much neede hook: - -\newtoks\everytabulate - -% An example of its usage: - -\appendtoks \optimizeverbatimfalse \to \everytabulate -\appendtoks \chardef\recodeverbatimmode\plustwo \to \everytabulate - -% A status variable: - -\chardef\tabulatepass=0 - -\def\tabulateparameter#1{\csname\??tt\currenttabulate#1\endcsname} - -\bgroup - \catcode`\|=\@@other \gdef\@@otherbar{|} - \catcode`\|=\@@active \gdef\@@useotherbar{\let|\@@otherbar} -\egroup - -\def\dofinalstarttabulate[#1][#2][#3]% identifier sub preamble - {\edef\currenttabulate{#1::#2}% - \ifinsidefloat \else - \whitespace - \tabulateparameter\c!before - \fi - \bgroup - \resetcharacteralign - % todo: spacing around tabulate when bodyfont is set - % expansion en test needed ? - \splittabulatetrue - \processaction - [\tabulateparameter\c!split] - [% \v!yes=>\splittabulatetrue, - % \v!repeat=>\splittabulatetrue, % todo, default yes - \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 - \widowpenalty\zerocount % otherwise lines are not broken - \clubpenalty \zerocount % but overlap in funny ways - \the\everytabulate - \tabulateparameter\c!inner - \scratchdimen\leftskip - \advance\scratchdimen \hangindent - \doifvalue{\??tt\currenttabulate\c!indenting}\v!yes - {\advance\scratchdimen \parindent}% \ctxparindent - \edef\tabulateindent{\the\scratchdimen}% - \!!toksb\emptytoks - \def\dorepeat*##1##2% - {\dorecurse{##1}{\appendtoks##2\to\!!toksb}\do}% - \def\do - {\futurelet\next\dodo}% - \def\dodo % \@EAEAEA gebruiken - {\ifx\next\relax - % exit - \else\ifx*\next - \let\next\dorepeat - \else\ifx\bgroup\next - \let\next\dododo - \else - \let\next\dodododo - \fi\fi\fi - \next}% - \def\dododo##1% - {\appendtoks{##1}\to\!!toksb\do}% - \def\dodododo##1% - {\appendtoks##1\to\!!toksb\do}% - \global\tabulatecolumn\zerocount -% \do#3\relax -\bgroup\@@useotherbar\expanded{\egroup\noexpand\do#3\relax}% - \processcontent - {\e!stop#1}% \currenttabulate} - \tabulatecontent - {\@EA\processtabulate\@EA[\the\!!toksb]}} - -\chardef\tabulatetype=0 - -% 0 = NC column next EQ equal column -% 1 = RC column raw RQ equal column raw -% 2 = HC column hook HQ equal column hook - -\newif\iftabulatefirstflushed - -\def\tabulateEQ - {\iftabulatefirstflushed\else\tabulateparameter{EQ}\fi - \global\tabulateequalfalse} - -% \def\tabulatenormalcolumn#1% -% {&\iftabulateequal\tabulateEQ\fi&\global\chardef\tabulatetype#1&} -% -% \def\tabulateequalcolumn#1% -% {&\tabulateEQ&\global\chardef\tabulatetype#1&} -% -% however, \unskip en \ignorespaces permit usage in complex XML/\starttabulate - -\def\tabulatenormalcolumn#1% - {\unskip&\iftabulateequal\tabulateEQ\fi&\global\chardef\tabulatetype#1&% - \ignorespaces} - -\def\tabulateequalcolumn#1% - {\unskip&\tabulateEQ&\global\chardef\tabulatetype#1&% - \ignorespaces} - -\def\tabulateautocolumn - {\tabulatenormalcolumn\zerocount - \ifnum\tabulatecolumn>\tabulatecolumns\relax - \expandafter\NR - \else - \expandafter\ignorespaces % interferes with the more tricky hooks - \fi} - -\def\setquicktabulate#1% see \startlegend \startgiven - {\let#1\tabulateautocolumn - \let\\\tabulateautocolumn} - -%\def\dotabulateruleseperator -% {\vskip\strutdp} - -\def\dotabulateruleseperator % can be sped up - {\bgroup - \let\factor\!!plusone - \scratchskip\strutdp - \ExpandFirstAfter\processallactionsinset - [\tabulateparameter\c!distance] - [ \v!blank=>\scratchskip\bigskipamount, - \v!depth=>\scratchskip\strutdp, - \v!small=>\def\factor{.25}, - \v!medium=>\def\factor{.5}, - \v!big=>, - \v!none=>\scratchskip\zeropoint\def\factor{0}, - \v!grid=>\scratchskip\zeropoint\def\factor{0}, - \s!unknown=>\scratchskip\commalistelement]% - \scratchdimen\factor\scratchskip - \ifconditional\tabulatesomeamble\kern\else\vskip\fi\scratchdimen % new - \egroup} - -\def\dodotabulaterule#1% - {\color - [\tabulateparameter\c!rulecolor] - {\scratchdimen\tabulateparameter\c!rulethickness#1}} - -\def\dotabulaterule - {\dodotabulaterule - {\hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen\relax - \doifvalue{\??tt\currenttabulate\c!distance}\v!grid - {\kern-\scratchdimen}}} % experimental tm-prikkels - -\def\dotabulatelinerule - {\multispan\totaltabulatecolumns % \multispan is a plain macro - % for the moment this one - \strut\hskip\tabulateparameter\c!margin - % neg values are ok ! - \hskip\tabulateindent % new august 2003 - \dodotabulaterule - {\!!heighta.5\lineheight - \advance\!!heighta-\strutdepth - \!!deptha-\!!heighta - \advance\!!deptha\scratchdimen - \leaders\hrule\!!height\!!heighta\!!depth\!!deptha\hfill}% - \cr} - -%D When set to true, no (less) break optimization is done. - -\newif\iftolerantTABLEbreak - -%D The main processing macro is large but splitting it up -%D would make things less clear. - -\def\doregistertabulateparoptions - {\iftrialtypesetting \else - \registerparoptions - \ifinsidefloat - % that is, an unbreakable one - \global\let\registertabulateparoptions\empty - \else - % unsafe in crossing pages, at each b... - % \global\let\registertabulateparoptions\empty - \fi - \fi} - -\appendtoks - \global\let\registertabulateparoptions\doregistertabulateparoptions -\to \everytabulate - -\newtoks\everytabulaterow - -\appendtoks - \registertabulateparoptions -\to \everytabulaterow - -\def\flushtabulateindent - {\ifnum\tabulatecolumn=\zerocount - \hbox to \tabulateindent - {% we now have a local hsize, and since we want to - % register positional info (i.e. real hsizes) we - % need to reconstitute the original hsize - \advance\hsize\tabulateindent - % this is indeed rather messy and took a few hours - % to dis/uncover - \the\everytabulaterow - \hss}% - \fi} - -\def\totaltabulatecolumns{0} - -\def\handletabulatedigits{\digits} - -%D Beware, we cannot use \type {\unexpanded} on \type {\HL} -%D cum suis, since \TEX's hard coded noalign lookahead fails -%D on it! I mistakenly added this for a while. - -\chardef\tabulaterepeathead\zerocount - -\newcount\noftabulatelines -\newcount\totalnoftabulatelines -\newcount\minusnoftabulatelines - -\setvalue{\??tt:\c!align:\v!normal}{0} -\setvalue{\??tt:\c!align:\v!right }{1} -\setvalue{\??tt:\c!align:\v!left }{2} -\setvalue{\??tt:\c!align:\v!middle}{3} - -\setvalue{\??tt:\c!header:\v!repeat}{\plusone} -\setvalue{\??tt:\c!header:\v!text }{\plustwo} - -\bgroup \catcode`\|=\@@other - -\gdef\processtabulate[|#1|]% in the process of optimizing - {\tabulateunit\tabulateparameter\c!unit - \checkfulltabulatecontent - \globallet\tabulateruledepth \!!zeropoint - \globallet\tabulateruleheight\!!zeropoint - \edef\@@tabulatealign{\executeifdefined{\??tt:\c!align:\tabulateparameter\c!align}0}% -% \ExpandFirstAfter\processaction % use \setalignmentswitch instead -% [\tabulateparameter\c!align] -% [ \v!normal=>\def\@@tabulatealign{0},% = default value -% \v!right=>\def\@@tabulatealign{1},% chardefs gebruiken -% \v!left=>\def\@@tabulatealign{2},% -% \v!middle=>\def\@@tabulatealign{3},% -% \s!default=>\def\@@tabulatealign{0},% -% \s!unknown=>\def\@@tabulatealign{0}]% - \let\pretabskip\!!zeropoint - \def\postabskip{.5\tabulateunit}% - \global\tabulatecolumns\zerocount - \global\nofautotabulate\zerocount - \global\noftabulatelines\zerocount - \totalnoftabulatelines\noftabulatelines - \minusnoftabulatelines\noftabulatelines - \global\tabulatepwidth\zeropoint - \global\tabulateequalfalse - \resettabulatepheight - \ifinsidesplitfloat - \donetrue - \else\ifinsidefloat - \donefalse - \else - \donetrue - \fi\fi - \ifdone - \chardef\tabulaterepeathead\executeifdefined{\??tt:\c!header:\tabulateparameter\c!header}\zerocount -% \processaction -% [\tabulateparameter\c!header] -% [\v!repeat=>\chardef\tabulaterepeathead\plusone, -% \v!text=>\chardef\tabulaterepeathead\plustwo]% - \fi - \unexpanded \def\NC{\tabulatenormalcolumn0}% - \unexpanded \def\RC{\tabulatenormalcolumn1}% - \unexpanded \def\HC{\tabulatenormalcolumn2}% - \unexpanded \def\EQ{\tabulateequalcolumn 0}% - \unexpanded \def\RQ{\tabulateequalcolumn 1}% - \unexpanded \def\HQ{\tabulateequalcolumn 2}% - \unexpanded \def\NG{\NC\handletabulatecharalign}% - \unexpanded \def\NN{\NC\handletabulatedigits}% new, undocumented, test first - \unexpanded \def\ND{\NC\handletabulatedigits}% same, for old times sake - \def\tabulaterule{\HR}% a rule with lineheight - \def\tabulateline{\HL}% just a spaced rule - \def\tabulateautorule{\doHR\plusone}% - \def\tabulateautoline{\doHL\plusone}% - \def\HR{\doHR\zerocount} - \def\HL{\doHL\zerocount} - \unexpanded \def\NR % next row - {\global\advance\noftabulatelines\plusone - \global\tabulatefirstflushedfalse - \global\tabulateequalfalse - \global\tabulatecolumn\zerocount - \resettabulatepheight - \unskip\unskip\crcr\flushtabulated - \TABLEnoalign - {\iftolerantTABLEbreak\else - \ifconditional\tabulatesomeamble \ifcase\tabulaterepeathead \else - \allowbreak - \fi \fi - \ifnum\noftabulatelines=\plusone - \dotabulatenobreak - \else\ifnum\noftabulatelines=\minusnoftabulatelines - \ifnum\tabulatemaxplines<\plustwo - \dotabulatenobreak - \else - \allowbreak % needed with pbreak prevention - \fi - \else - \allowbreak % needed with pbreak prevention - \fi\fi - \fi - \global\tabulatefirstflushedfalse}}% - \let\HL\empty % not needed - \let\SR\NR \let\AR\NR - \let\FL\empty \let\FR\NR - \let\ML\empty \let\MR\NR - \let\LL\empty \let\LR\NR - \let\doHR\gobbleoneargument - \let\doHL\gobbleoneargument - \global\let\flushtabulated\empty -% \let\savedbar|\let|\nexttabulate - \tabskip\zeropoint - \ifdim\tabulateparameter\c!margin>\zeropoint - \!!toksa{&\flushtabulateindent\strut##% - \tabskip\tabulateparameter\c!margin\strut - &##\tabskip\zeropoint}% - \else - \!!toksa{&\flushtabulateindent\strut##% - &##\tabskip\zeropoint}% - \fi - \tabulatewidth\zeropoint - % |#1X|\relax - \nexttabulate #1X|\relax - \scratchcounter\tabulatecolumns - \multiply\scratchcounter3% - \advance\scratchcounter4% - \edef\totaltabulatecolumns{\the\scratchcounter}% - \tabulatewidth\zeropoint - % \dorecurse\tabulatecolumns % can be made faster - % {\doifundefinedelse{\@@tabbox@@\recurselevel} - % {\expandafter\newbox\csname\@@tabbox@@\recurselevel\endcsname}% - % {\global\setbox\csname\@@tabbox@@\recurselevel\endcsname\box\voidb@x}}% - \initializetableboxes\tabulatecolumns - \appendtoks&##\to\!!toksa - \appendtoks\global\advance\tabulatecolumn\plusone\to\!!toksa - \appendtoks\NC\unskip\unskip\crcr\flushtabulated\to\tabulatedummy % no count - \global\tabulatecolumn\zerocount - \resettabulatepheight - \def\bskip - {\setbox\tabulatebox\vbox\bgroup - \global\let\tabulatehook\notabulatehook}% - \def\eskip - {\par\egroup - \global\let\tabulatehook\dotabulatehook}% - \def\xbskip - {\hbox\bgroup\vbox\bgroup - \global\let\tabulatehook\notabulatehook}% - \def\xeskip - {\par\egroup\egroup - \global\let\tabulatehook\dotabulatehook}% - % \let|\savedbar - \global\let\tabulatehook\dotabulatehook - \doifvalue{\??tt\currenttabulate\c!indenting}\v!no\forgetparindent - \ifinsidefloat - \let\tabulateindent\!!zeropoint - \else - \setlocalhsize \hsize\localhsize - \fi - \dontcomplain - \forgetall % hm, interference with \forgetparindent ^^^ probably bug, to be solved - \setbox0\vbox % outside \if because of line counting - {\notesenabledfalse - \let\tabulateindent\!!zeropoint - \trialtypesettingtrue % very important - \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}}% - \ifnum\nofautotabulate>\zerocount - % so, even if the natural size is larger, in the final - % run, we force the calculated width - \tabulatewidth\hsize - \advance\tabulatewidth -\wd0 - \advance\tabulatewidth -\tabulatepwidth - \ifnum\nofautotabulate>\zerocount - \divide\tabulatewidth \nofautotabulate\relax - \fi - \fi - \def\xbskip{\bskip}% - \def\xeskip{\eskip}% - \ifsplittabulate - \splittopskip\strutht - \global\let\flushtabulatedindeed\empty - \long\def\bbskip - {\ifvoid\tablebox\tabulatecolumn - \ifx\flushtabulatedindeed\empty\else - \setbox0\hbox - \fi - \fi}% - \def\bskip - {\ifvoid\tablebox\tabulatecolumn - \global\setbox\tablebox\tabulatecolumn\vbox - \bgroup - \global\let\tabulatehook\notabulatehook - \ifautotabulate\hsize\tabulatewidth\fi - % \begstrut % interferes with pre-\pars - % evt: \appendtoks\begstrut\to\everypar - \ignorespaces - \def\eskip - {\par\egroup - \settabulatepheight - \global\let\tabulatehook\dotabulatehook - \splitofftabulatebox}% - \else - \let\eskip\empty - \dontcomplain - \global\let\tabulatehook\dotabulatehook - \expandafter\splitofftabulatebox - \fi}% - \gdef\flushtabulated - {\TABLEnoalign % noalign % no interference ! - {\global\let\flushtabulatedindeed\empty - \global\tabulatecolumn\zerocount - \handletabulatepbreak - \dorecurse\tabulatecolumns % was: \noftabcolumns - {\ifvoid\tablebox\recurselevel\else - \gdef\flushtabulatedindeed{\the\tabulatedummy}% - \fi}% - \global\tabulatefirstflushedtrue}% - \flushtabulatedindeed}% - \else - % tabhook op alles ? - \def\bskip - {\vtop\bgroup - \ifautotabulate\hsize\tabulatewidth\fi - % \begstrut % interferes with pre-\pars - % evt: \appendtoks\begstrut\to\everypar - \ignorespaces}% - \def\eskip % vertical strut added august 2003 - {\par\verticalstrut\vskip-\struttotal\egroup}% - \fi - \totalnoftabulatelines\noftabulatelines - \minusnoftabulatelines\numexpr\noftabulatelines+\minusone\relax - \global\noftabulatelines\zerocount - \def\doHL##1% ##1 ignored - {\TABLEnoalign - {\csname - \ifnum\noftabulatelines=\zerocount F\else - \ifnum\noftabulatelines=\totalnoftabulatelines L\else - M\fi\fi - L\endcsname}}% - \def\doHR##1% horizontal rule line (break untested) - {\TABLEnoalign - {\globallet\TABLEautoline\dotabulatelinerule - \ifcase##1\or - \ifnum\noftabulatelines=\zerocount - \gdef\TABLEautoline{\TABLEnoalign{}}% - \else\ifnum\noftabulatelines=\totalnoftabulatelines - \gdef\TABLEautoline{\TABLEnoalign{}}% - \fi\fi - \fi - \dotabulatenobreak}% - \TABLEautoline - \TABLEnoalign - {\nobreak - \ifx\TABLEautoline\dotabulatelinerule\kern-\lineheight\fi - \ifnum\noftabulatelines=\totalnoftabulatelines - \@EA\dotabulatenobreak - \else - \@EA\allowbreak - \fi}% - \TABLEautoline - \TABLEnoalign - {\dotabulatenobreak}}% - \doifelsevalue{\??tt\currenttabulate\c!rule}\v!line - {\let\HL \HR - \let\tabulateautoline\tabulateautorule - \let\tabulateline \tabulaterule}% - {\def\HL{\doHL\zerocount}}% - \def\tablebaselinecorrection - {\def\dobaselinecorrection - {\vskip-\prevdepth - \vskip\strutdp - \vskip\strutdp}% - \baselinecorrection}% - \def\FL{\TABLEnoalign - {\ifinsidefloat\else - \doifemptyvalue{\??tt\currenttabulate\c!before} % no expansion - {\tablebaselinecorrection}% - \fi - \dotabulaterule - \dotabulatenobreak - \dotabulateruleseperator - \prevdepth\strutdp - \dotabulatenobreak}}% - \def\ML{\TABLEnoalign - {\dotabulateruleseperator - \dotabulaterule - \ifnum\noftabulatelines>\plusone - \ifnum\noftabulatelines<\minusnoftabulatelines - \vskip\topskip\allowbreak\vskip-\topskip - \vskip-\tabulateparameter\c!rulethickness - \dotabulaterule - \fi - \fi - \dotabulateruleseperator}}% - \def\LL{\TABLEnoalign - {\dotabulatenobreak - \dotabulateruleseperator - \dotabulatenobreak - \dotabulaterule - \ifinsidefloat\else - \doifemptyvalue{\??tt\currenttabulate\c!after} % no expansion - {\vskip\strutdp - \verticalstrut - \vskip-\struttotal}% - \fi}}% - \chardef\tabulatepass\plustwo - % - \ifcase\tabulaterepeathead - \ifinsidesplitfloat - \setbox\tabulatebox\vbox \bgroup - \else - \startframedcontent[\tabulateparameter\c!frame]% - \fi - \else - \setbox\tabulatebox\vbox \bgroup - \fi - % - \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}% - \prevdepth\strutdp % nog eens beter, temporary hack - \doifvalue{\??tt\currenttabulate\c!distance}\v!grid - {\vskip-\strutdp}% experimental tm-prikkels - % - \ifcase\tabulaterepeathead - \ifinsidesplitfloat - \egroup \splittabulatebox\tabulatebox - \else - \stopframedcontent - \fi - \else - \egroup \splittabulatebox\tabulatebox - \fi - % - \egroup - \ifinsidefloat \else - \tabulateparameter\c!after - \fi - \egroup} - -\egroup - -% \setuptabulate[split=yes,header=text,title=Vervolg van Tabel] -% -% % \starttabulatehead -% % \NC test \NC hans\NC \NR -% % \stoptabulatehead -% -% \starttabulate -% \NC test \NC \input tufte \relax \NC \NR -% \NC test \NC \input knuth \relax \NC \NR -% \NC test \NC \input knuth \relax \NC \NR -% \NC test \NC \input tufte \relax \NC \NR -% \NC test \NC \input tufte \relax \NC \NR -% \NC test \NC \input tufte \relax \NC \NR -% \stoptabulate - -% \def\splittabulatebox#1% #1 <> 0/2 / derived from the one in core-ntb.tex -% {\ifinsidefloat -% \unvbox#1% -% \else -% \ifcase\tabulaterepeathead\or -% \setbox2\copy#1% -% \setbox2\vsplit2 to \lineheight -% \setbox2\vbox{\unvbox2}% -% \fi -% \doloop -% {\setbox0\vsplit#1 to \onepoint % \lineheight -% \ifdim\pagegoal<\maxdimen -% \donetrue -% \else\ifdim\pagetotal=\zeropoint -% \donetrue -% \else -% \donefalse -% \fi\fi -% \ifdone -% \setbox0\vbox{\unvbox0}% -% \dimen0\pagetotal -% \advance\dimen0\dp0 -% \advance\dimen0\ht0 -% \ifdim\dimen0>\pagegoal -% \bgroup \page \egroup % make sure that local vars are kept -% \ifcase\tabulaterepeathead\or -% \unvcopy2 -% \or -% \hbox{\strut\tabulateparameter\c!title}% -% \fi -% \fi -% \fi -% % test this on icare checklists / quite hacky ! ! ! -% \ifdim\ht0>\tabulateparameter\c!rulethickness\else -% \kern-2\ht0 % brrrr -% \fi -% % -% \unvbox0 -% \allowbreak -% \ifvoid#1 \exitloop \fi}% -% \fi} - -\def\splittabulatebox#1% #1 <> 0/2 / derived from the one in core-ntb.tex - {\ifinsidesplitfloat - \dosplittabulatebox#1% - \else\ifinsidefloat - \unvbox#1% - \else - \dosplittabulatebox#1% - \fi\fi} - -\def\dosplittabulatebox#1% - {\resettsplit - \def\tsplitminimumfreelines{2}% - \def\tsplitminimumfreespace{0pt}% - \setbox\tsplitcontent\box#1% - \ifcase\tabulaterepeathead\or - \setbox\tsplithead\vsplit\tsplitcontent to \lineheight - \setbox\tsplithead\vbox{\unvbox\tsplithead}% - \or - \setbox\tsplithead\vbox{\hbox{\strut\tabulateparameter\c!title}}% - \fi - \handletsplit} - -%D \starttyping -%D \setuptabulate[split=no,rule=line] -%D -%D \starttabulate -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule -%D \stoptabulate -%D \stoptyping - -% \starttabulatie[|mc|] -% \NC \digits{100.000,00} \NC\NR -% \NC \digits{@10.000,00} \NC\NR -% \NC \digits{@@@.100,00} \NC\NR -% \NC \digits{@@@.@10,@@} \NC\NR -% \NC \digits{@@@.@@1,@@} \NC\NR -% \stoptabulatie -% -% \starttabulatie[|mc|] -% \ND 100.000,00 \NC\NR -% \ND @10.000,00 \NC\NR -% \ND @@@.100,00 \NC\NR -% \ND @@@.@10,@@ \NC\NR -% \ND @@@.@@1,@@ \NC\NR -% \stoptabulatie -% -% \starttabulatie[|c|] -% \ND $100.000,00$ \NC\NR -% \ND $@10.000,00$ \NC\NR -% \ND $@@@.100,00$ \NC\NR -% \ND $@@@.@10,@@$ \NC\NR -% \ND $@@@.@@1,@@$ \NC\NR -% \stoptabulatie -% -% \starttabulatie[|c|] -% \NC $\digits 100.000,00 $ \NC\NR -% \NC $\digits @10.000,00 $ \NC\NR -% \NC $\digits @@@.100,00 $ \NC\NR -% \NC $\digits @@@.@10,@@ $ \NC\NR -% \NC $\digits @@@.@@1,@@ $ \NC\NR -% \stoptabulatie -% -% \starttabulatie[|c|] -% \NC \digits $100.000,00$ \NC\NR -% \NC \digits $@10.000,00$ \NC\NR -% \NC \digits $@@@.100,00$ \NC\NR -% \NC \digits $@@@.@10,@@$ \NC\NR -% \NC \digits $@@@.@@1,@@$ \NC\NR -% \stoptabulatie - -\def\setuptabulate - {\dotripleempty\dosetuptabulate} - -\def\dosetuptabulate[#1][#2][#3]% - {\ifthirdargument - \getparameters[\??tt#1::#2][#3]% - \else\ifsecondargument - \getparameters[\??tt#1::][#2]% - \else - \getparameters[\??tt\v!tabulate::][#1]% - \fi\fi} - -\setuptabulate - [\c!unit=1em, - EQ={:}, - \c!frame=\v!off, - \c!bodyfont=, - \c!rule=\v!normal, - \c!rulecolor=, - \c!rulethickness=\linewidth, - \c!inner=, - \c!before=\blank, - \c!after=\blank, - \c!distance={\v!depth,\v!medium}, - \c!align=\v!normal, - \c!margin=\!!zeropoint, - \c!split=\v!auto, - \c!header=\v!yes, - \c!title=, - \c!indenting=\v!no] - -\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-tsp.tex b/tex/context/base/core-tsp.tex deleted file mode 100644 index e9f0e7d58..000000000 --- a/tex/context/base/core-tsp.tex +++ /dev/null @@ -1,427 +0,0 @@ -%D \module -%D [ file=core-tsp, -%D version=2000.10.20, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Splitting 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. - -\writestatus{loading}{Context OTR Macros / Floating Bodies} - -%D The code in this file is move here from other places. - -\unprotect - -% only to be used with single tokens (will be prim) - -\ifx\htdp\undefined \def\htdp#1{\dimexpr\ht#1+\dp#1\relax} \fi - -%D Although the name resembles floats, and therefore this should be -%D a page module, we decided to make it core functionality because the -%D table code depends on it. Othrwise there would be too much -%D overloading afterwards involved. Actually, the float part is rather -%D generic and not that related to floats. - -% \splitfloat [settings] {\placetable[optional args]{test}} {content} - -\definenumber - [\??si] - [\c!way=\v!by\v!text, - \c!conversion=\@@siconversion] - -\def\setupfloatsplitting - {\dodoubleargument\getparameters[\??si]} - -\newif\ifinsidesplitfloat % will become chardef - -\newtoks \everysplitfloatsetup - -\def\splitfloat - {\dosingleempty\dosplitfloat} - -\ifx\floatcaptionsuffix\undefined \else - \let\floatcaptionsuffix\empty % will become \splitfloatcaptionsuffix -\fi - -\def\extrasplitfloatlines{0} - -\def\dosplitfloat[#1]#2% nog dubbele refs - {\bgroup - \global\setfalse\splitfloatdone - \aftergroup\checksplitfloat - \insidefloattrue - \insidesplitfloattrue - \getparameters[\??si][#1]% - \resetnumber[\??si]% - \def\floatcaptionsuffix{\convertednumber[\??si]}% - \let\extrasplitfloatlines\@@silines - \the\everysplitfloatsetup - \def\splitfloatcommand{#2}% - \global\settrue \onlyonesplitofffloat - \global\setfalse\somenextplitofffloat - \dopushsavedfloats - \@@sibefore - \let\next} % \bgroup - -\def\checksplitfloat - {\ifconditional\splitfloatdone\else - \blank{\tttf \getmessage\m!floatblocks{13}\empty}\blank - \showmessage\m!floatblocks{13}\empty - \fi} - -\settrue \onlyonesplitofffloat -\setfalse\somenextplitofffloat - -%D When \type {inbetween} is made empty instead of the -%D default \type {\page}, we will get delayed flushing -%D and text may continue below the graphic. -%D -%D \starttyping -%D \dorecurse{2}{\input tufte } -%D -%D \splitfloat[lines=auto,inbetween=] -%D {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}} -%D {\bTABLE[split=yes] -%D \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR -%D \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR -%D \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR -%D \bTR \bTD 14 \eTD \bTD test \eTD \eTR -%D \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR -%D \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR -%D \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR -%D \bTR \bTD 24 \eTD \bTD test \eTD \eTR -%D \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR -%D \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR -%D \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR -%D \bTR \bTD 34 \eTD \bTD test \eTD \eTR -%D \eTABLE} -%D -%D \dorecurse{10}{\input tufte } -%D \stoptyping - -\newconditional\splitfloatdone - -\def\dodowithsplitofffloat - {\dowithnextbox - {\forgetall - \dontcomplain - \global\settrue\splitfloatdone - \chardef\nodelocationmode\zerocount % bypass auto-renumbering - \incrementnumber[\??si]% - \ifcase\rawnumber[\??si]\or \ifconditional\onlyonesplitofffloat - \let\floatcaptionsuffix\empty - \fi \fi - \bgroup - \ifconditional\somenextplitofffloat - \settrue\retainfloatnumber -\notesenabledfalse % best here, experimental, brrr; test with note in caption - \else - \setfalse\retainfloatnumber - \fi - \splitfloatcommand{\box\nextbox}% - \egroup - \ifconditional\somenextplitofffloat - \doifelsenothing\@@siinbetween - {\ifconditional\splitfloatfirstdone\else\page\fi} - \@@siinbetween - \else - \@@siafter - \dopopsavedfloats - \doflushsavedfloats - \fi - \global\settrue\splitfloatfirstdone}% - \vbox} - -\def\nodowithsplitofffloat - {\dowithnextbox - {\forgetall - \dontcomplain - \box\nextbox % maybe an option to unvbox - \global\settrue\splitfloatfirstdone}% - \vbox} - -\def\dochecksplitofffloat#1% box - {\ifinsidesplitfloat - \ifdim\ht#1=\zeropoint - \global\setfalse\somenextplitofffloat - \else - \global\settrue \somenextplitofffloat - \global\setfalse\onlyonesplitofffloat - \fi - \fi} - -\def\analyzesplitfloatcaption#1% depends on page-flt - {\doif\extrasplitfloatlines\v!auto - {\bgroup - \settrue\retainfloatnumber - \chardef\nodelocationmode\zerocount - \forcelocalfloats - \setuplocalfloats[\c!before=,\c!after=,\c!inbetween=]% - \splitfloatcommand{\hbox to \wd#1{\strut}}% dummy line - \setbox\scratchbox\vbox{\flushlocalfloats}% - \getnoflines{\ht\scratchbox}% - \resetlocalfloats - \advance\noflines\minusone % compensate dummy line - \expanded{\egroup\noexpand\edef\noexpand\extrasplitfloatlines{\the\noflines}}}} - -% \def\analyzesplitfloatcaption#1% -% {\edef\extrasplitfloatlines{11}} - -\def\dowithsplitofffloat % nextbox - {\ifinsidesplitfloat - \expandafter\dodowithsplitofffloat - \else - \expandafter\nodowithsplitofffloat - \fi} - -\def\doifnotinsidesplitfloat - {\ifinsidesplitfloat\expandafter\gobbleoneargument\fi} - -%D Some defaults: - -\setupfloatsplitting - [\c!conversion=\v!character, % \v!romannumerals - \c!lines=3, - \c!before=, - \c!inbetween=\page, - \c!after=] - -%D Table splitter, on top of previous code: - -\newbox\tsplitcontent -\newbox\tsplitresult -\newbox\tsplithead -\newbox\tsplitnext -\newbox\tsplittail - -\def\resettsplit{% only \def's starting a a new line are seen by the dep checker - \def\tsplitminimumfreelines{0}% - \def\tsplitminimumfreespace{0pt}% - \setbox\tsplitcontent \vbox{}% - \setbox\tsplitresult \vbox{}% - \setbox\tsplithead \vbox{}% - \setbox\tsplitnext \vbox{}% - \setbox\tsplittail \vbox{}% - \let\tsplitbeforeresult\donothing - \let\tsplitafterresult \donothing - \let\tsplitinbetween \donothing - \let\tsplitbefore \donothing - \let\tsplitafter \donothing - \let\postprocesstsplit \donothing -} - -\resettsplit - -% todo: keep tail to rest, so we need a lookahead - -\newconditional\splitfloatfirstdone - -\def\handletsplit - {\analyzesplitfloatcaption\tsplitcontent - \global\setfalse\splitfloatfirstdone - \testpagesync % new, sync, but still tricky - [\tsplitminimumfreelines] - [\dimexpr\tsplitminimumfreespace+\extrasplitfloatlines\lineheight\relax]% - \setbox\scratchbox\vbox{\tsplitinbetween}% - \edef\tsplitinbetweenheight{\the\htdp\scratchbox}% etex - \!!doneafalse - \doloop - {\ifinsidecolumns - % brrr, assumes empty columns - \global\setfalse\splitfloatfirstdone - \scratchdimen\textheight - \!!donectrue - \else - \ifconditional\splitfloatfirstdone - \scratchdimen\textheight - \!!donectrue - \else\ifdim\pagegoal<\maxdimen - \scratchdimen\dimexpr\pagegoal-\pagetotal\relax - \!!donecfalse - \else - \scratchdimen\textheight - \!!donectrue - \fi\fi - \fi - \scratchdimen\dimexpr\scratchdimen-\tsplitinbetweenheight-\tsplitminimumfreespace-\extrasplitfloatlines\lineheight\relax - \ifdim\htdp\tsplittail>\zeropoint - \advance\scratchdimen-\htdp\tsplittail - \fi - \setbox\tsplitresult\vbox - {\ifdim\ht\tsplithead>\zeropoint - \unvcopy\tsplithead - \tsplitinbetween - \fi}% - \if!!donea\else\ifdim\ht\tsplitnext>\zeropoint - \setbox\tsplithead\box\tsplitnext - \fi\fi - \!!doneatrue - \ifdim\ht\tsplitresult>\zeropoint - \!!donedtrue % table head - \else - \!!donedfalse % no tablehead - \fi - \splittopskip\zeropoint - \doloop - {\setbox\scratchbox\vsplit\tsplitcontent to \onepoint % \lineheight - \setbox\scratchbox\vbox{\unvbox\scratchbox}% - \ifdim\dimexpr\scratchdimen-\htdp\scratchbox-\htdp\tsplitresult\relax>\zeropoint - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvbox\scratchbox}% - \ifvoid\tsplitcontent \exitloop \fi - \else\if!!doned - % we only have a tablehead so far - \setbox\tsplitresult\vbox{\unvbox\tsplitresult\unvbox\scratchbox}% - \exitloop - \else\if!!donec - % we have text height available, but the (one) cell is too - % large to fit, so, in order to avoid loops/deadcycles we do: - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvbox\scratchbox}% - \exitloop - \else - \setbox\tsplitcontent\vbox - {\unvbox\scratchbox - \tsplitinbetween - \ifvoid\tsplitcontent\else\unvbox\tsplitcontent\fi}% - \exitloop - \fi\fi\fi - \!!donedfalse - \!!donecfalse}% - \postprocesstsplit - \dochecksplitofffloat\tsplitcontent - \ifvoid\tsplitcontent - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvcopy\tsplittail}% - \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% - \doifnotinsidesplitfloat\tsplitafter - \endgraf - \exitloop - \else - % hack - \ifdim\pagegoal<\maxdimen - \global\pagegoal\dimexpr\pagegoal+\lineheight\relax % etex - \fi - % brrr - \ifdim\ht\tsplitresult>\zeropoint - \setbox\tsplitresult\vbox - {\unvbox\tsplitresult - \tsplitinbetween - \unvcopy\tsplittail}% - \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% - \doifnotinsidesplitfloat\tsplitafter - \endgraf - \fi - \ifinsidecolumns - \doifnotinsidesplitfloat\goodbreak - \else - \doifnotinsidesplitfloat\page - \fi - \fi}% - \global\setfalse\splitfloatfirstdone} % we can use this one for tests - -\protect \endinput - -% test cases - -% \setupTABLE[split=repeat] -% -% \input tufte \endgraf -% \splitfloat[lines=11] -% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} -% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE} -% \input tufte \page -% -% \input tufte \endgraf -% \splitfloat[lines=0] -% {} -% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE} -% \input tufte \endgraf \page -% -% \input tufte \endgraf -% \bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE -% \input tufte \page - -% \setuptabulate[split=yes] -% -% \input tufte \endgraf -% \splitfloat[lines=11] -% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} -% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate} -% \input tufte \page -% -% \input tufte \endgraf -% \splitfloat[lines=0] -% {} -% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate} -% \input tufte \page -% -% \input tufte \endgraf -% \starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate -% \input tufte \page - -% \setuptables[split=yes] -% -% \newtoks\TestToks -% -% \TestToks\emptytoks -% \appendtoks\starttablehead\to\TestToks -% \dorecurse{3}{\appendtoks\VL head \VL head \VL \SR\to\TestToks} -% \appendtoks\stoptablehead\to\TestToks -% \appendtoks\starttabletail\to\TestToks -% \dorecurse{3}{\appendtoks\VL tail \VL tail \VL \SR\to\TestToks} -% \appendtoks\stoptabletail\to\TestToks -% \appendtoks\starttables[|c|c|]\to\TestToks -% \dorecurse{100}{\appendtoks\VL test \VL test \VL \SR\to\TestToks} -% \appendtoks\stoptables\to\TestToks -% -% \input tufte \endgraf -% \splitfloat[lines=auto] % [lines=11] -% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} -% {\the\TestToks} -% \input tufte \page -% -% \input tufte \endgraf -% \splitfloat[lines=0] -% {} -% {\the\TestToks} -% \input tufte \page -% -% \input tufte \endgraf -% \the\TestToks -% \input tufte \page -% -% multiple floats -% -% \starttext -% \dorecurse{3}{\input tufte } \endgraf -% \dorecurse{5}{\placefigure{}{\framed[height=.5\textheight]{}}} -% \splitfloat[lines=auto,inbetween=] -% {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}} -% {\bTABLE[split=yes] -% \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR -% \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR -% \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR -% \bTR \bTD 14 \eTD \bTD test \eTD \eTR -% \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR -% \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR -% \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR -% \bTR \bTD 24 \eTD \bTD test \eTD \eTR -% \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR -% \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR -% \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR -% \bTR \bTD 34 \eTD \bTD test \eTD \eTR -% \eTABLE} -% \dorecurse{10}{\input tufte } -% \stoptext 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.

--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--

Variables are saved using in the previously defined table and passed @@ -32,39 +33,206 @@ directly access the variable using a call.

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

..

) -\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

..

+\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{ 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} \par \type<<....>> \par \type<<..<>..>> \par +% normal: \par \type{xx<..xx.. >..>xx} \par \type{<....>} \par \type{<....>} +% \setuptype[option=slanted] +% slanted: \par \type{xx<<..sl..<> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<>..>> \par +% slanted: \par \type{xx<<..sl.. xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<....>> \par +% \setuptype[option=none] +% none: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \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{ 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} \par \type<<....>> \par \type<<..<>..>> \par +% normal: \par \type{xx<..xx.. >..>xx} \par \type{<....>} \par \type{<....>} +% \setuptype[option=slanted] +% slanted: \par \type{xx<<..sl..<> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<>..>> \par +% slanted: \par \type{xx<<..sl.. xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<....>> \par +% \setuptype[option=none] +% none: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \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{ 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} \par \type<<....>> \par \type<<..<>..>> \par -% normal: \par \type{xx<..xx.. >..>xx} \par \type{<....>} \par \type{<....>} -% \setuptype[option=slanted] -% slanted: \par \type{xx<<..sl..<> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<>..>> \par -% slanted: \par \type{xx<<..sl.. xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<....>> \par -% \setuptype[option=none] -% none: \par \type{xx<<..xx..<> >>..>>xx} \par \type<<....>> \par \type<<..<>..>> \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-- +

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).

+ +

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.

+ +

Examples of usage can be found in the font related code.

+--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("\n") + f:write("\n") + if jobname then + f:write(format("\t%s\n",jobname)) + end + f:write("\t\n") + for _,v in ipairs(table.sortedkeys(found)) do + f:write(format("\t\t%s\n",found[v],v)) + end + f:write("\t\n") + f:write("\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-- +

This file is used when we want the input handlers to behave like +kpsewhich. What to do with the following:

+ + +{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} +$SELFAUTOLOC : /usr/tex/bin/platform +$SELFAUTODIR : /usr/tex/bin +$SELFAUTOPARENT : /usr/tex + + +

How about just forgetting about them?

+--ldx]]-- + +local suffixes = resolvers.suffixes +local formats = resolvers.formats + +suffixes['gf'] = { 'gf' } +suffixes['pk'] = { '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-- +

If you wondered abou tsome of the previous mappings, how about +the next bunch:

+--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-- +

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.

+ + +TEXMFCACHE=$TMP;$TEMP;$TMPDIR;$TEMPDIR;$HOME;$TEXMFVAR;$VARTEXMF;. + + +

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.

+--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 +% +% Ϭ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 -% -% \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.

--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.

--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.

--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.mkiv b/tex/context/base/font-col.mkiv new file mode 100644 index 000000000..22a67ac8e --- /dev/null +++ b/tex/context/base/font-col.mkiv @@ -0,0 +1,146 @@ +%D \module +%D [ file=font-col, +%D version=2008.06.11, +%D title=\CONTEXT\ Font Macros, +%D subtitle=Fallbacks (collections), +%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. + +% ! EXPERIMENTAL ! code will be made more nice + +% todo: missing only, force always, multiple fallbacks with test, scale +% +% \resetfontfallback [whatever] +% +% \definefontfallback [whatever] [Slanted] [0x0060-0x007F] [force=yes] +% \definefontfallback [whatever] [Bold] [0x0080-0x00FF,0x00A0-0x00AF] [rscale=1.2] +% \definefontfallback [whatever] [BoldSlanted] [0x00C0-0x00C7] [check=yes,force=yes] + +\writestatus{loading}{ConTeXt Font Macros / Collections} + +\registerctxluafile{font-col}{1.001} + +\unprotect + +\def\definefontfallback + {\doquadrupleempty\dodefinefontfallback} + +\def\dodefinefontfallback[#1][#2][#3][#4]% + {\ctxlua{fonts.collections.define("#1","#2",\!!bs#3\!!es,\!!bs#4\!!es)}} + +\def\resetfontfallback + {\dodoubleempty\doresetfontfallback} + +\def\doresetfontfallback[#1][#2]% + {\ctxlua{fonts.collections.reset("#1","#2")}} + +% add fallbacks to last font + +\def\dodefinefontfallbacks#1% + {\ctxlua{fonts.collections.prepare("#1")}} + +% we might as well move the handling to lua but then we need to pass the +% fallbacks, skewchar etc. + +\setfalse\doingfontfallbacks + +\def\dodefinefontfallbacksindeed#1% + {\begingroup + \settrue\doingfontfallbacks + \lastrawfontcall % sets current font id + \dodefinefontfallbacks#1% + \endgroup} + +\appendtoks + \ifconditional\doingfontfallbacks\else + \ifx\@@fontfallbacks\empty + \ifx\@@fontclassfallbacks\empty + \else + \dodefinefontfallbacksindeed\@@fontclassfallbacks + \fi + \else + \dodefinefontfallbacksindeed\@@fontfallbacks + \fi + \fi +\to\everydefinefont + +\def\dostartcloningfonts + {\bgroup + \let\savedfontspec\somefontspec} + +\def\dostopcloningfonts + {\egroup} + +\def\doclonefonta#1#2% kind of dododefinefont + {\ctxlua{fonts.collections.message("defining #1 (relative scale: #2)")}% + \autofontsizefalse + \let\lastfontidentifier\s!dummy + \def\localrelativefontsize{#2}% + \let\localabsolutefontsize\fontbody + \lowleveldefinefont{#1}\rawfontidentifier + \csname\rawfontidentifier\endcsname + \autofontsizefalse + %\setfontcharacteristics + }%\the\everyfontswitch} + +\def\doclonefontb#1% #2 + {\doclonefonta{#1 \savedfontspec}} + +% check : only replace when present in replacement font (default: no) +% force : force replacent even when basefont has glyph (default: yes) + +% \definefontfallback [whatever] [Slanted] [0x0060-0x007F] [force=yes] +% \definefontfallback [whatever] [Bold] [0x0080:0x00FF,0x00A0:0x00AF] [rscale=2.0] +% \definefontfallback [whatever] [BoldSlanted] ["00C0-"00C7] [check=yes,force=yes] +% \definefontfallback [whatever] [Mono] [latinextendeda] [force=yes] % 0x0100:0x017F +% \definefontfallback [whatever] [Mono] [latin extended a] [force=yes] % 0x0100:0x017F +% +% \definefontsynonym[SerifPlus][Serif][fallbacks=whatever] +% +% \definefont[MySerif][SerifPlus at 10pt] +% +% \startcolumns[n=6] +% \MySerif +% \dostepwiserecurse {0} {65000} {1} { +% \iffontchar\font\recurselevel +% {\tttf\uchexnumbers\recurselevel:} \char\recurselevel\par +% \fi +% } +% \stopcolumns + +% \definefontfeature[zh][mode=node,script=hang,lang=zhs] +% \definefontfallback[serifwhatever] [lmroman10-regular] [0x0000-0x0400][force=yes] +% \definefontfallback[serifboldwhatever] [lmroman10-bold] [0x0000-0x0400][force=yes] +% \definefontfallback[serifitalicwhatever] [lmroman10-italic] [0x0000-0x0400][force=yes] +% \definefontfallback[serifbolditalicwhatever][lmroman10-bolditalic][0x0000-0x0400][force=yes] +% +% \starttypescript [serif] [zhfont] +% \definefontsynonym [zhserif] [AdobeSongStd-Light] [features=zh,fallbacks=serifwhatever] +% \definefontsynonym [zhserifbold] [AdobeHeitiStd-Regular][features=zh,fallbacks=serifboldwhatever] +% \definefontsynonym [zhserifitalic] [AdobeKaitiStd-Regular][features=zh,fallbacks=serifitalicwhatever] +% \definefontsynonym [zhserifbolditalic][AdobeHeitiStd-Regular][features=zh,fallbacks=serifbolditalicwhatever] +% \stoptypescript +% +% \starttypescript [serif][zhfont][name] +% \definefontsynonym[Serif] [zhserif] % [fallbacks=serifwhatever] +% \definefontsynonym[SerifBold] [zhserifbold] % [fallbacks=serifboldwhatever] +% \definefontsynonym[SerifItalic] [zhserifitalic] % [fallbacks=serifitalicwhatever] +% \definefontsynonym[SerifBoldItalic] [zhserifbolditalic] % [fallbacks=serifbolditalicwhatever] +% \stoptypescript +% +% \starttypescript[myfont] +% \definetypeface[myfont][rm][serif][zhfont] +% \stoptypescript +% +% \usetypescript[myfont] \setupbodyfont[myfont,rm,12pt] +% +% \starttext +% fonts {\bf fonts} {\bi fonts} {\it fonts} +% \stoptext + +\protect \endinput diff --git a/tex/context/base/font-col.tex b/tex/context/base/font-col.tex deleted file mode 100644 index 3383b6515..000000000 --- a/tex/context/base/font-col.tex +++ /dev/null @@ -1,148 +0,0 @@ -%D \module -%D [ file=font-col, -%D version=2008.06.11, -%D title=\CONTEXT\ Font Macros, -%D subtitle=Fallbacks (collections), -%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. - -% ! EXPERIMENTAL ! code will be made more nice - -% todo: missing only, force always, multiple fallbacks with test, scale -% -% \resetfontfallback [whatever] -% -% \definefontfallback [whatever] [Slanted] [0x0060-0x007F] [force=yes] -% \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)} - -\registerctxluafile{font-col}{1.001} - -\unprotect - -\def\definefontfallback - {\doquadrupleempty\dodefinefontfallback} - -\def\dodefinefontfallback[#1][#2][#3][#4]% - {\ctxlua{fonts.collections.define("#1","#2",\!!bs#3\!!es,\!!bs#4\!!es)}} - -\def\resetfontfallback - {\dodoubleempty\doresetfontfallback} - -\def\doresetfontfallback[#1][#2]% - {\ctxlua{fonts.collections.reset("#1","#2")}} - -% add fallbacks to last font - -\def\dodefinefontfallbacks#1% - {\ctxlua{fonts.collections.prepare("#1")}} - -% we might as well move the handling to lua but then we need to pass the -% fallbacks, skewchar etc. - -\setfalse\doingfontfallbacks - -\def\dodefinefontfallbacksindeed#1% - {\begingroup - \settrue\doingfontfallbacks - \lastrawfontcall % sets current font id - \dodefinefontfallbacks#1% - \endgroup} - -\appendtoks - \ifconditional\doingfontfallbacks\else - \ifx\@@fontfallbacks\empty - \ifx\@@fontclassfallbacks\empty - \else - \dodefinefontfallbacksindeed\@@fontclassfallbacks - \fi - \else - \dodefinefontfallbacksindeed\@@fontfallbacks - \fi - \fi -\to\everydefinefont - -\def\dostartcloningfonts - {\bgroup - \let\savedfontspec\somefontspec} - -\def\dostopcloningfonts - {\egroup} - -\def\doclonefonta#1#2% kind of dododefinefont - {\ctxlua{fonts.collections.message("defining #1 (relative scale: #2)")}% - \autofontsizefalse - \let\lastfontidentifier\s!dummy - \def\localrelativefontsize{#2}% - \let\localabsolutefontsize\fontbody - \lowleveldefinefont{#1}\rawfontidentifier - \csname\rawfontidentifier\endcsname - \autofontsizefalse - %\setfontcharacteristics - }%\the\everyfontswitch} - -\def\doclonefontb#1% #2 - {\doclonefonta{#1 \savedfontspec}} - -% check : only replace when present in replacement font (default: no) -% force : force replacent even when basefont has glyph (default: yes) - -% \definefontfallback [whatever] [Slanted] [0x0060-0x007F] [force=yes] -% \definefontfallback [whatever] [Bold] [0x0080:0x00FF,0x00A0:0x00AF] [rscale=2.0] -% \definefontfallback [whatever] [BoldSlanted] ["00C0-"00C7] [check=yes,force=yes] -% \definefontfallback [whatever] [Mono] [latinextendeda] [force=yes] % 0x0100:0x017F -% \definefontfallback [whatever] [Mono] [latin extended a] [force=yes] % 0x0100:0x017F -% -% \definefontsynonym[SerifPlus][Serif][fallbacks=whatever] -% -% \definefont[MySerif][SerifPlus at 10pt] -% -% \startcolumns[n=6] -% \MySerif -% \dostepwiserecurse {0} {65000} {1} { -% \iffontchar\font\recurselevel -% {\tttf\uchexnumbers\recurselevel:} \char\recurselevel\par -% \fi -% } -% \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] -% \definefontfallback[serifitalicwhatever] [lmroman10-italic] [0x0000-0x0400][force=yes] -% \definefontfallback[serifbolditalicwhatever][lmroman10-bolditalic][0x0000-0x0400][force=yes] -% -% \starttypescript [serif] [zhfont] -% \definefontsynonym [zhserif] [AdobeSongStd-Light] [features=zh,fallbacks=serifwhatever] -% \definefontsynonym [zhserifbold] [AdobeHeitiStd-Regular][features=zh,fallbacks=serifboldwhatever] -% \definefontsynonym [zhserifitalic] [AdobeKaitiStd-Regular][features=zh,fallbacks=serifitalicwhatever] -% \definefontsynonym [zhserifbolditalic][AdobeHeitiStd-Regular][features=zh,fallbacks=serifbolditalicwhatever] -% \stoptypescript -% -% \starttypescript [serif][zhfont][name] -% \definefontsynonym[Serif] [zhserif] % [fallbacks=serifwhatever] -% \definefontsynonym[SerifBold] [zhserifbold] % [fallbacks=serifboldwhatever] -% \definefontsynonym[SerifItalic] [zhserifitalic] % [fallbacks=serifitalicwhatever] -% \definefontsynonym[SerifBoldItalic] [zhserifbolditalic] % [fallbacks=serifbolditalicwhatever] -% \stoptypescript -% -% \starttypescript[myfont] -% \definetypeface[myfont][rm][serif][zhfont] -% \stoptypescript -% -% \usetypescript[myfont] \setupbodyfont[myfont,rm,12pt] -% -% \starttext -% fonts {\bf fonts} {\bi fonts} {\it fonts} -% \stoptext - -\protect \endinput 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-- +

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:

+situations:

+ + +name:xetex like specs +name@virtual font spec +name*context specification + +--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--

Here we deal with defining fonts. We do so by intercepting the @@ -18,43 +22,30 @@ default loader that only handles .

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-- -

Choosing a font by name and specififying its size is only part of the -game. In order to prevent complex commands, 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.

- -

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.

- --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--

We hardly gain anything when we cache the final (pre scaled) table. But it can be handy for debugging.

@@ -84,7 +75,7 @@ and prepares a table that will move along as we proceed.

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--

A unique hash value is generated by:

--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--

We can resolve the filename using the next function:

--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.

--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.

--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-- -

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:

-situations:

- - -name:xetex like specs -name@virtual font spec -name*context specification - - -

Of course one can always define more.

---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--

We need to check for default features. For this we provide a helper function.

--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.

--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

We overload both the and readers.

--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--

Because encodings are going to disappear, we don't bother defining them in tables. But we may do so some day, for consistency.

@@ -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.

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-- +

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.

+--ldx]]-- + +fonts.triggers = fonts.triggers or { } +fonts.initializers = fonts.initializers or { } +fonts.initializers.common = fonts.initializers.common or { } + +local initializers = fonts.initializers + +--[[ldx-- +

This feature will remove inter-digit kerns.

+--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-- +

This feature will give all glyphs an equal height and/or depth. Valid +values are none, height, depth and +both.

+--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-- +

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 files.

+--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--

This is very experimental code!

--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'] = {

Not much is happening here.

--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 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 {fontclass, defaultfontclass} %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 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 \macros +%D {textonly} +%D +%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\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} -%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\getglobalfontparameters - {\expandafter\dogetglobalfontparameter\@@fontdata,]=,} +\def\dododefinefontsynonymnop[#1]% + {\let\@@ff@@features \undefined + \let\@@ff@@fallbacks\undefined + \expandafter\dogetfontparameternop#1,]=,} -\def\dogetfontparameter#1=#2,% - {\if]#1\else - \expandafter\def\csname\??ff\@@fontfile#1\endcsname{#2}% - \expandafter\dogetfontparameter +\def\dododefinefontsynonymyes[#1]% + {\let\@@ff@@features \undefined + \let\@@ff@@fallbacks\undefined + \expandafter\dogetfontparameteryes#1,]=,} + +\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,46 +1065,13 @@ %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 @@ -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\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}% + \processcommacommand[\fontstylelist]\dododocommand}% + \processcommacommand[\fontalternativelist]\dodocommand}% + \processcommacommand[\fontsizelist]\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} - -\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 @@ -2320,29 +1867,7 @@ \let\fontalternative = \defaultfontalternative \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}} +\let\fontsize = \defaultfontsize %D When \type {\loadfontfileoncetrue}, such files are %D only loaded once! This permits redundant loading, but at @@ -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. +%D In good old \TEX, the old style numerals were often taken +%D from the math fonts. No longer. -% older -% -% \definefont [os] [OldStyle sa *] -% \definefont [frak] [Fraktur sa *] -% \definefont [goth] [Gothic sa *] -% \definefont [cal] [Calligraphic sa *] -% \definefont [bbd] [Blackboard sa *] -% -% newer - -\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] @@ -4294,42 +3670,12 @@ \definealternativestyle [\v!smallcaps] [\sc] [\sc] \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 - \fi} -\def\dogetfontparameternop#1=#2,% - {\if]#1% - \dodododefinefontsynonymnop - \else - \expandafter\def\csname @@ff@@#1\endcsname{#2}% - \expandafter\dogetfontparameternop +\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\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\definestyleinstance + {\doquadrupleargument\dodefinestyleinstance} -\def\updatefontparametersyes - {\@@thefeaturesyes \somefontname - \@@thefallbacksyes\somefontname - \@@theskewcharyes \somefontname} -\def\updatefontparametersnop - {\@@thefeaturesnop \somefontname - \@@thefallbacksnop\somefontname - \@@theskewcharnop \somefontname} - -\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-- +

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.

+--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--

Eventually this code will disappear because map files are kind of obsolete. Some code may move to runtime or auxiliary modules.

@@ -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-- -

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.

+

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.

+ + +we loop over all lookups +for each lookup we do a run over the list of glyphs +but we only process them for features that are enabled +if we're dealing with a contextual lookup, we loop over all contexts +in that loop we quit at a match and then process the list of sublookups +we always continue after the match + + +

In we do this for each font that is used in a list, so in +practice we have quite some nested loops.

+ +

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).

+ +

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.

+--ldx]]-- -

As with the code, we may decide to store more information -in the table.

+fonts = fonts or { } +fonts.otf = fonts.otf or { } +fonts.tfm = fonts.tfm or { } -

Incrementing the version number will force a re-cache. We jump the -number by one when there's a fix in the library or - code that results in different tables.

---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--

We start with a lot of tables and related functions.

--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.global_fields = table.tohash { + "lookups", + "glyphs", + "subfonts", + "luatex", + "pfminfo", + "cidinfo", + "tables", + "names", + "unicodes", + "names", + "anchor_classes", + "kern_classes", + "gpos", + "gsub" } -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.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-- +

Here we go.

+--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-- -

Here we go.

---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) +otf.enhancers["cleanup aat"] = function(data,filename) + if otf.cleanup_aat then 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 - } +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,91 +771,239 @@ 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 - logs.report("load otf","problems with unicode %s of kern %s at glyph %s",vc,k,index) - else - local mkl = mykerns[vl] - if not mkl then - mkl = { } - mykerns[v.lookup] = mkl +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 - if type(uvc) == "table" then - for u=1,#uvc do - mkl[uvc[u]] = vo - end - else - mkl[uvc] = vo + 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 - glyph.mykerns = mykerns - glyph.kerns = nil -- saves space and time - mkdone = true end end - if mkdone then - logs.report("load otf", "replacing 'kerns' tables by 'mykerns' tables") + 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 - 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 + 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) - 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 + +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 -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["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-- +

This module is a bit more split up that I'd like but since we also want to test +with plain it has to be so. This module is part of +and discussion about improvements and functionality mostly happens on the + mailing list.

+ +

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.

+ +

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.

+ +

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 users ask for it.

+ +

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.

+ +

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 + 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 has to include +then in the output eventually.

+ +

The raw table as it coms from gets reorganized in to fit out needs. +In 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).

+ +

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.

+ +

As with the code, we may decide to store more information in the + table.

+ +

Incrementing the version number will force a re-cache. We jump the number by one +when there's a fix in the library or code that +results in different tables.

+--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 "" + 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-- +

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.

+--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-- +

I will implement multiple chain replacements once I run into a font that uses +it. It's not that complex to handle.

+--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-- +

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:

+ + +xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx + + +

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.

+--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-- +

Here we replace start by a single variant, First we delete the rest of the +match.

+--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-- +

Here we replace start by a sequence of new glyphs. First we delete the rest of +the match.

+--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-- +

Here we replace start by new glyph. First we delete the rest of the match.

+--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-- +

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).

+--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--

This module implements a name to filename resolver. Names are resolved using a table that has keys filtered from the font related files.

--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--

It would make sense to implement the filters in the related modules, but to keep the overview, we define them here.

--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.

--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).

--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-- -

A handy helper.

---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--

Fallbacks, not permanent but a transition thing.

--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--

Here we only implement a few helper functions.

--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--

The next function encapsulates the standard loader as supplied by .

--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 uses a negative multiple of 1000 as a signal for a font scaled based on the design size.

--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.)

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 @@ -348,235 +593,6 @@ function tfm.scale(tfmtable, scaledpoints) return t end ---[[ldx-- -

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.

---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-- -

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.

---ldx]]-- - -fonts.initializers = fonts.initializers or { } -fonts.initializers.common = fonts.initializers.common or { } - ---[[ldx-- -

This feature will remove inter-digit kerns.

---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-- -

This feature will give all glyphs an equal height and/or depth. Valid -values are none, height, depth and -both.

---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-- -

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 files.

---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--

Analyzers run per script and/or language and are needed in order to process features right.

@@ -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-- -

We move marks into the components list. This saves much nasty testing later on.

---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.mkii b/tex/context/base/font-uni.mkii new file mode 100644 index 000000000..1b8ce8e43 --- /dev/null +++ b/tex/context/base/font-uni.mkii @@ -0,0 +1,444 @@ +%D \module +%D [ file=font-uni, +%D version=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 \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 +%D that some mixture of one and two byte encoding was used, +%D which he confirmed. Since \TEX\ normally does not use the +%D characters $>127$, so as long as the two byte characters +%D have a first character with code $>127$, we can use active +%D characters to handle them. In an optimistic mood, I called +%D this module the \UNICODE\ font module. In the module that +%D handles Chinese, we will see that some more interpretation +%D is involved, which is why the macros handling those +%D characters look ahead. + +\unprotect + +%D \macros +%D {handleunicodeflowglyph, uchar, +%D handleunicodeglyph, insertunicodeglyph, +%D unicodeposition, unicodeone, unicodetwo} +%D +%D For the moment \UNICODE\ support is rather primitive but +%D nevertheless effective. The reference to \UNICODE\ is not +%D entirely correct, since in many cases one will use \quote +%D {older} mappings, but in principle, \UNICODE\ can be +%D supported. +%D +%D We expect each character to come as two eight bit +%D characters. Those doubles are handled by making all +%D characters in the range $>127$ active, so that they can +%D pick up the next one, and act upon both their values. +%D Internally only numbers are used. A first implementation +%D simply internally prefixed the second part of the \UNICODE\ +%D pair with \type {\string} or \type {\char}, but this was +%D not that handy when it came to testing those values. +%D Because in principle we are dealing with an encoding, the +%D making active is handled in \type {enco-uni}. +%D +%D There are two commands to handle unicode characters: +%D +%D \starttyping +%D \handleunicodeflowglyph{number}{character} +%D \uchar{number}{number} +%D \stoptyping +%D +%D The first one can be assigned to an active character, the +%D second one can be used to directly access a glyph. Both +%D command call \type {\handleunicodeglyph} that in turn +%D calls \type {\insertunicodeglyph}. Both can be overruled +%D in specialized modules. The low level command \type +%D {\unicodeglyph} can best be left untouched, which is not +%D so much a problem because there is a hook into this macro: +%D \type {\unicodecharcommand}. +%D +%D In most cases one will redefine \type {\handleunicodeglyph} +%D in such a way that it identifies special situations first, +%D takes some actions next, calls \type {\insertunicodeglyph}, +%D if needed with \type {\unicodecharcommand} changed, and +%D finally does some finishing: +%D +%D \starttyping +%D \def\handleunicodeglyph +%D {take actions based on \unicodeone-two-position cq. \nextutoken +%D redefine \unicodecharcommand if needed +%D expand \insertunicodeglyph +%D take some final actions} +%D \stoptyping + +\newcount\unicodeposition + +%D The multistep approach is needed to pick up the second +%D token, since this token can have any value and any +%D catcode. + +% the \relax trick prevents eating up the space (needed for +% korean + +\def\handleunicodeflowglyph#1#2% + {\begingroup + \edef\unicodeone{#1}% + \@EA\afterassignment\@EA\dohandleunicodeflowglyph % two redundant ea's + \@EA\chardef\@EA\nexttoken\@EA`\string#2\relax} + +\def\dohandleunicodeflowglyph\relax + {\futurelet\nextutoken\dodohandleunicodeflowglyph} + +\def\dodohandleunicodeflowglyph % todo tex (or maybe no longer) + {\edef\unicodetwo{\the\nexttoken}% + \unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax + \handleunicodeglyph + \endgroup} + +\unexpanded\def\uchar#1#2% use as standalone glyph + {\begingroup + \edef\unicodeone{#1}% + \edef\unicodetwo{#2}% + \unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax + \handleunicodeglyph + \endgroup} + +\let\nextutoken\relax + +\unexpanded\def\lookaheaduchar#1#2% + {\def\dolookaheaduchar{\uchar{#1}{#2}\let\nextutoken\relax}% + \futurelet\nextutoken\dolookaheaduchar} + +\def\dohandleucflowglyph + {\unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax + \handleunicodeglyph + \endgroup} + +\unexpanded\def\uc#1#2% used in tricky situations + {\begingroup + \edef\unicodeone{#1}% + \edef\unicodetwo{#2}% + \futurelet\nextutoken\dohandleucflowglyph} + +\def\insertunicodeglyph + {\unicodeglyph\unicodeone\unicodetwo} + +\let\handleunicodeglyph\insertunicodeglyph + +%D One can use the \type {\unicodeposition} in the macros +%D that handle pre and post material. + +%D \macros +%D {unicodestyle, unicodecharcommand} +%D +%D Each character pair will become one glyph. Because \TEX\ +%D cannot handle fonts with more that 256 characters, we use +%D \TFM\ files for each range. The first character of the pair +%D is appended to the name of a font, and the second is used to +%D access the glyph in that font. This means that a particular +%D font is split up in subfonts with names in the range: +%D +%D \starttyping +%D 80 ... ff +%D \stoptyping +%D +%D The \type {} as well as the composed name are +%D mapped ones. The next macros take care of this mapping. +%D Let us assume that the next mapping has taken place, +%D +%D \starttyping +%D \definefontsynonym [UnicodeRegular] [gbsong] +%D \stoptyping +%D +%D Let us also assume that we are dealing with the range \type +%D {b1}. Given that a font name results from: +%D +%D \starttyping +%D \truefontname{\truefontname{UnicodeRegular}b1} +%D \stoptyping +%D +%D we get \type {gbsongb1}. The outer \type {\truefontname} +%D takes care of additional mapping, so when we say: +%D +%D \starttyping +%D \definefontsynonym [gbsongb1] [gbsong-b1] +%D \stoptyping +%D +%D the filename used will be \type {gbsong-b1}. From the next +%D definition it will be clear that other fontshapes are also +%D supported. The prefix \type {Unicode} is mapped! +%D +%D The command \type {\unicodecharcommand} can be used to +%D handle special cases. At that moment \type {1em} is known. + +\def\unicodestyle + {\truefontname\s!Unicode\fontstylesuffix} + +\let\unicodecharcommand\firstofoneargument + +\unexpanded\def\unicodeglyph#1#2% watch the double mapping + {\begingroup + \getvalue{@@\currentucharmapping\strippedcsname\uchar}{#1}{#2}% map to a to hex font range + \bodyfontsize\unicodescale\bodyfontsize + % readable: + % \doifelsefontsynonym{\unicodestyle\unicodeone} + % {\font\unicodefont=\truefontname{\unicodestyle\unicodeone} + % at \currentfontscale\bodyfontsize} + % {\font\unicodefont=\truefontname{\truefontname\unicodestyle\unicodeone} + % at \currentfontscale\bodyfontsize}% + % unreadable but more efficient: + \font\unicodefont=\truefontname{\doifelsefontsynonym{\unicodestyle + \unicodeone}\empty\truefontname\unicodestyle\unicodeone} + at \currentfontscale\bodyfontsize + \unicodestrut % off by default + \unicodefont\unicodecharcommand{\char\unicodetwo\relax}% + \endgroup} + +%D This handler is used by default, for instance in: +%D +%D \starttyping +%D \defineunicodefont [MySwitch] [MyFont] % [strut=no,command=\insertunicodeglyph] +%D +%D \definefontsynonym [MyFontRegular40] [Sans] +%D \definefontsynonym [MyFontBold40] [SansBold] +%D +%D {\MySwitch \uchar{"40}{`a}} +%D {\MySwitch \bf \uchar{"40}{`a}} +%D \stoptyping +%D +%D \starttyping +%D \definefontsynonym [MyFontRegular] [Sans] +%D \definefontsynonym [MyFontBold] [SansBold] +%D \stoptyping +%D +%D Is also possible, but in that case the number is appended to the raw font +%D name! + +%D \macros +%D {currentucharmapping,defineucharmapping} +%D +%D A (plane,char) pair can be remapped using a uchar mapping +%D function. The default mapping is to convert the plane to a +%D lowercase hexadecimal number, and leave the number +%D untouched. The current remapping is kept in a macro. + +\let\currentucharmapping\s!default + +\def\defineucharmapping#1% + {\setvalue{@@#1\strippedcsname\uchar}} + +\defineucharmapping{\s!default}#1#2% + {\edef\unicodeone{\lchexnumbers{#1}}\edef\unicodetwo{#2}} + +%D An example of a remapping is the following: +%D +%D \starttyping +%D \defineucharmapping{GBK}#1#2% +%D {\unicodeposition=#1 +%D \advance\unicodeposition -129 +%D \multiply\unicodeposition 190 +%D \advance\unicodeposition #2 +%D \advance\unicodeposition-\ifnum#2>127 65\else64\fi +%D \dorepositionunicode} +%D \stoptyping +%D +%D This maps the GBK vector onto a compact GBK one. The +%D auxiliary macro is defined here as a goody. + +\def\dorepositionunicode + {\dosetdivision\unicodeposition{256}\scratchcounter + \advance\scratchcounter \plusone + \edef\unicodeone{\ifnum\scratchcounter<10 0\fi\the\scratchcounter}% + \dosetmodulo\unicodeposition{256}\scratchcounter + \edef\unicodetwo{\the\scratchcounter}} + +%D \macros +%D {setunicodestrut, setunicodescale, nextutoken, +%D handleunicodeglyph, insertunicodeglyph} +%D +%D A careful analysis of the previous macros, learns that the +%D process of mapping comes down to: +%D +%D \startitemize[packed,n] +%D \item taking care of preceding material (and spacing) +%D \item defining the font at \type {\currentfontscale} $\times$ +%D \type {\unicodescale} $\times$ \type {\bodyfontsize} +%D \item inserting a \type {\unicodestrut} +%D \item inserting the character (glyph) +%D \item executing some actions afterwards +%D \stopitemize +%D +%D The actions before and after placing the glyph, is up to +%D the user supplied handler. This handler (\type +%D {\handleunicodeglpyh}) must, at a certain moment, insert +%D the glyph using \type {\insertunicodeglyph} + +\def\setunicodescale#1% + {\def\unicodescale{#1}} + +\def\dosetunicodestrut#1#2% height depth + {\def\unicodestrut + {\vrule + \!!width \zeropoint + \!!height#1\strutht + \!!depth #2\strutdp + \relax}} + +\def\setunicodestrut#1#2% height depth + {\ifdim#1\strutht>\zeropoint + \dosetunicodestrut{#1}{#2}% + \else\ifdim#1\strutdp>\zeropoint + \dosetunicodestrut{#1}{#2}% + \else + \let\unicodestrut\empty + \fi\fi} + +\def\resetunicodestrut + {\let\unicodestrut\empty} + +%D The additional scaling and strut default to: + +\setunicodescale{1} +\setunicodestrut{1}{1} + +%D But better is not to have a strut added by default: + +\resetunicodestrut + +%D The actual code for the additional actions as well as +%D specific spacing is handled outside these routines. The +%D character after the two that are under treatment is +%D available in \type {\nextutoken}. + +%D \macros +%D {defineunicodefont, setupunicodefont} +%D +%D Apart from this rather low level implementation, we also +%D provide a more user friendly alternative. Given that one +%D has defined: +%D +%D \starttyping +%D \defineunicodefont +%D [SimChi] [SimplifiedChinese] +%D [\c!scale=0.85, +%D \c!height=1.25, +%D \c!depth=1.00, +%D \c!interlinespaceinterlinie=yes, +%D \c!conversion=\chinesenumber, +%D \c!command=\handlechineseunicodeglyph] +%D \stoptyping +%D +%D Together with: +%D +%D \starttyping +%D \definefontsynonym [SimplifiedChineseRegular] [gbsong] +%D \definefontsynonym [SimplifiedChineseSlanted] [gbsongsl] +%D \stoptyping +%D +%D we can now switch to Simplified Chinese by saying \type +%D {SimChi}. Some values can be changed afterwards with +%D +%D \starttyping +%D \setupunicodefont[SimChi][...=...] +%D \stoptyping +%D +%D Specific initializations can be assigned to \type +%D {commands}. + +\def\defineunicodefont + {\dotripleempty\dodefineunicodefont} + +\def\dodefineunicodefont[#1][#2][#3]% + {\doifassignmentelse{#3} + {\setupunicodefont[#1][#3]} + {\doifelsenothing{#3} + {\setupunicodefont[#1][#3]} + {\copyparameters + [\??uc#1][\??uc#3] + [\c!height,\c!depth,\c!scale,\c!commands,\c!strut, + \c!interlinespace,\c!command,\c!conversion]}}% + \doifelsenothing{#2} + {\setvalue{#1}{[uc font #1 undefined]}} + {\setvalue{\??uc#1\c!file}{#2}% + \doifundefined{\??ff#2\s!Bold} + {\definefontsynonym[#2\s!Bold] [#2\s!Regular]% + \definefontsynonym[#2\s!Slanted] [#2\s!Regular]% + \definefontsynonym[#2\s!Italic] [#2\s!Regular]% + \definefontsynonym[#2\s!BoldSlanted][#2\s!Slanted]% + \definefontsynonym[#2\s!BoldItalic] [#2\s!Italic]}% + \unexpanded\setvalue{#1}{\enableunicodefont{#1}}}} + +\def\setupunicodefont + {\dodoubleempty\dosetupunicodefont} + +\def\dosetupunicodefont[#1][#2]% also predefines + {\doifundefined{\??uc#1\c!command} + {\copyparameters + [\??uc#1][\??uc\s!default] + [\c!height,\c!depth,\c!scale,\c!commands,\v!strut, + \c!interlinespace,\c!command,\c!conversion]}% + \getparameters[\??uc#1][#2]} + +\def\enableunicodefont#1% + {\definefontsynonym[\s!Unicode][\getvalue{\??uc#1\c!file}]% + \def\unicodescale {\getvalue{\??uc#1\c!scale}}% + \def\unicodeheight {\getvalue{\??uc#1\c!height}}% + \def\unicodedepth {\getvalue{\??uc#1\c!depth}}% + \def\unicodedigits {\getvalue{\??uc#1\c!conversion}}% + \def\handleunicodeglyph {\getvalue{\??uc#1\c!command}}% + \doifnot\currentregime{utf}{\enableregime[unicode]}% + % the following \relax's are realy needed + \doifvalue{\??uc#1\c!interlinespace}\v!yes + \setupinterlinespace\relax + \doifelsevalue{\??uc#1\c!strut}\v!yes + {\setunicodestrut\unicodeheight\unicodedepth} + {\resetunicodestrut}% + \getvalue{\??uc#1\c!commands}\relax} + +%D \macros +%D {unicodedigits} +%D +%D For convenience we also predefine a number conversion +%D macro: + +\let\unicodedigits\number + +%D Because we cannot be sure of the pressence of all font +%D styles, we remap some by default. + +\definefontsynonym [\s!Unicode\s!Bold] [\s!Unicode\s!Regular] +\definefontsynonym [\s!Unicode\s!Slanted] [\s!Unicode\s!Regular] +\definefontsynonym [\s!Unicode\s!Italic] [\s!Unicode\s!Regular] +\definefontsynonym [\s!Unicode\s!BoldSlanted] [\s!Unicode\s!Slanted] +\definefontsynonym [\s!Unicode\s!BoldItalic] [\s!Unicode\s!Italic] + +\setupunicodefont + [\s!default] + [\c!height=1, + \c!depth=1, + \c!scale=1, + \c!strut=\v!no, + \c!interlinespace=\v!no, + \c!command=\insertunicodeglyph, + \c!conversion=\number] + +\protect \endinput 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-uni.tex b/tex/context/base/font-uni.tex deleted file mode 100644 index 7d4f3e442..000000000 --- a/tex/context/base/font-uni.tex +++ /dev/null @@ -1,465 +0,0 @@ -%D \module -%D [ file=font-uni, -%D version=1999.10.10, -%D title=\CONTEXT\ Font Macros, -%D subtitle=\UNICODE\ 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 Font Macros / UNICODE Support} - -%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 -%D that some mixture of one and two byte encoding was used, -%D which he confirmed. Since \TEX\ normally does not use the -%D characters $>127$, so as long as the two byte characters -%D have a first character with code $>127$, we can use active -%D characters to handle them. In an optimistic mood, I called -%D this module the \UNICODE\ font module. In the module that -%D handles Chinese, we will see that some more interpretation -%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 -%D {handleunicodeflowglyph, uchar, -%D handleunicodeglyph, insertunicodeglyph, -%D unicodeposition, unicodeone, unicodetwo} -%D -%D For the moment \UNICODE\ support is rather primitive but -%D nevertheless effective. The reference to \UNICODE\ is not -%D entirely correct, since in many cases one will use \quote -%D {older} mappings, but in principle, \UNICODE\ can be -%D supported. -%D -%D We expect each character to come as two eight bit -%D characters. Those doubles are handled by making all -%D characters in the range $>127$ active, so that they can -%D pick up the next one, and act upon both their values. -%D Internally only numbers are used. A first implementation -%D simply internally prefixed the second part of the \UNICODE\ -%D pair with \type {\string} or \type {\char}, but this was -%D not that handy when it came to testing those values. -%D Because in principle we are dealing with an encoding, the -%D making active is handled in \type {enco-uni}. -%D -%D There are two commands to handle unicode characters: -%D -%D \starttyping -%D \handleunicodeflowglyph{number}{character} -%D \uchar{number}{number} -%D \stoptyping -%D -%D The first one can be assigned to an active character, the -%D second one can be used to directly access a glyph. Both -%D command call \type {\handleunicodeglyph} that in turn -%D calls \type {\insertunicodeglyph}. Both can be overruled -%D in specialized modules. The low level command \type -%D {\unicodeglyph} can best be left untouched, which is not -%D so much a problem because there is a hook into this macro: -%D \type {\unicodecharcommand}. -%D -%D In most cases one will redefine \type {\handleunicodeglyph} -%D in such a way that it identifies special situations first, -%D takes some actions next, calls \type {\insertunicodeglyph}, -%D if needed with \type {\unicodecharcommand} changed, and -%D finally does some finishing: -%D -%D \starttyping -%D \def\handleunicodeglyph -%D {take actions based on \unicodeone-two-position cq. \nextutoken -%D redefine \unicodecharcommand if needed -%D expand \insertunicodeglyph -%D take some final actions} -%D \stoptyping - -\newcount\unicodeposition - -%D The multistep approach is needed to pick up the second -%D token, since this token can have any value and any -%D catcode. - -% the \relax trick prevents eating up the space (needed for -% korean - -\def\handleunicodeflowglyph#1#2% - {\begingroup - \edef\unicodeone{#1}% - \@EA\afterassignment\@EA\dohandleunicodeflowglyph % two redundant ea's - \@EA\chardef\@EA\nexttoken\@EA`\string#2\relax} - -\def\dohandleunicodeflowglyph\relax - {\futurelet\nextutoken\dodohandleunicodeflowglyph} - -\def\dodohandleunicodeflowglyph % todo tex (or maybe no longer) - {\edef\unicodetwo{\the\nexttoken}% - \unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax - \handleunicodeglyph - \endgroup} - -\unexpanded\def\uchar#1#2% use as standalone glyph - {\begingroup - \edef\unicodeone{#1}% - \edef\unicodetwo{#2}% - \unicodeposition\numexpr\unicodeone*256+\unicodetwo\relax - \handleunicodeglyph - \endgroup} - -\let\nextutoken\relax - -\unexpanded\def\lookaheaduchar#1#2% - {\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 - \endgroup} - -\unexpanded\def\uc#1#2% used in tricky situations - {\begingroup - \edef\unicodeone{#1}% - \edef\unicodetwo{#2}% - \futurelet\nextutoken\dohandleucflowglyph} - -\def\insertunicodeglyph - {\unicodeglyph\unicodeone\unicodetwo} - -\let\handleunicodeglyph\insertunicodeglyph - -%D One can use the \type {\unicodeposition} in the macros -%D that handle pre and post material. - -%D \macros -%D {unicodestyle, unicodecharcommand} -%D -%D Each character pair will become one glyph. Because \TEX\ -%D cannot handle fonts with more that 256 characters, we use -%D \TFM\ files for each range. The first character of the pair -%D is appended to the name of a font, and the second is used to -%D access the glyph in that font. This means that a particular -%D font is split up in subfonts with names in the range: -%D -%D \starttyping -%D 80 ... ff -%D \stoptyping -%D -%D The \type {} as well as the composed name are -%D mapped ones. The next macros take care of this mapping. -%D Let us assume that the next mapping has taken place, -%D -%D \starttyping -%D \definefontsynonym [UnicodeRegular] [gbsong] -%D \stoptyping -%D -%D Let us also assume that we are dealing with the range \type -%D {b1}. Given that a font name results from: -%D -%D \starttyping -%D \truefontname{\truefontname{UnicodeRegular}b1} -%D \stoptyping -%D -%D we get \type {gbsongb1}. The outer \type {\truefontname} -%D takes care of additional mapping, so when we say: -%D -%D \starttyping -%D \definefontsynonym [gbsongb1] [gbsong-b1] -%D \stoptyping -%D -%D the filename used will be \type {gbsong-b1}. From the next -%D definition it will be clear that other fontshapes are also -%D supported. The prefix \type {Unicode} is mapped! -%D -%D The command \type {\unicodecharcommand} can be used to -%D handle special cases. At that moment \type {1em} is known. - -\def\unicodestyle - {\truefontname\s!Unicode\fontstylesuffix} - -\let\unicodecharcommand\firstofoneargument - -\unexpanded\def\unicodeglyph#1#2% watch the double mapping - {\begingroup - \getvalue{@@\currentucharmapping\strippedcsname\uchar}{#1}{#2}% map to a to hex font range - \bodyfontsize\unicodescale\bodyfontsize - % readable: - % \doifelsefontsynonym{\unicodestyle\unicodeone} - % {\font\unicodefont=\truefontname{\unicodestyle\unicodeone} - % at \currentfontscale\bodyfontsize} - % {\font\unicodefont=\truefontname{\truefontname\unicodestyle\unicodeone} - % at \currentfontscale\bodyfontsize}% - % unreadable but more efficient: - \font\unicodefont=\truefontname{\doifelsefontsynonym{\unicodestyle - \unicodeone}\empty\truefontname\unicodestyle\unicodeone} - at \currentfontscale\bodyfontsize - \unicodestrut % off by default - \unicodefont\unicodecharcommand{\char\unicodetwo\relax}% - \endgroup} - -%D This handler is used by default, for instance in: -%D -%D \starttyping -%D \defineunicodefont [MySwitch] [MyFont] % [strut=no,command=\insertunicodeglyph] -%D -%D \definefontsynonym [MyFontRegular40] [Sans] -%D \definefontsynonym [MyFontBold40] [SansBold] -%D -%D {\MySwitch \uchar{"40}{`a}} -%D {\MySwitch \bf \uchar{"40}{`a}} -%D \stoptyping -%D -%D \starttyping -%D \definefontsynonym [MyFontRegular] [Sans] -%D \definefontsynonym [MyFontBold] [SansBold] -%D \stoptyping -%D -%D Is also possible, but in that case the number is appended to the raw font -%D name! - -%D \macros -%D {currentucharmapping,defineucharmapping} -%D -%D A (plane,char) pair can be remapped using a uchar mapping -%D function. The default mapping is to convert the plane to a -%D lowercase hexadecimal number, and leave the number -%D untouched. The current remapping is kept in a macro. - -\let\currentucharmapping\s!default - -\def\defineucharmapping#1% - {\setvalue{@@#1\strippedcsname\uchar}} - -\defineucharmapping{\s!default}#1#2% - {\edef\unicodeone{\lchexnumbers{#1}}\edef\unicodetwo{#2}} - -%D An example of a remapping is the following: -%D -%D \starttyping -%D \defineucharmapping{GBK}#1#2% -%D {\unicodeposition=#1 -%D \advance\unicodeposition -129 -%D \multiply\unicodeposition 190 -%D \advance\unicodeposition #2 -%D \advance\unicodeposition-\ifnum#2>127 65\else64\fi -%D \dorepositionunicode} -%D \stoptyping -%D -%D This maps the GBK vector onto a compact GBK one. The -%D auxiliary macro is defined here as a goody. - -\def\dorepositionunicode - {\dosetdivision\unicodeposition{256}\scratchcounter - \advance\scratchcounter \plusone - \edef\unicodeone{\ifnum\scratchcounter<10 0\fi\the\scratchcounter}% - \dosetmodulo\unicodeposition{256}\scratchcounter - \edef\unicodetwo{\the\scratchcounter}} - -%D \macros -%D {setunicodestrut, setunicodescale, nextutoken, -%D handleunicodeglyph, insertunicodeglyph} -%D -%D A careful analysis of the previous macros, learns that the -%D process of mapping comes down to: -%D -%D \startitemize[packed,n] -%D \item taking care of preceding material (and spacing) -%D \item defining the font at \type {\currentfontscale} $\times$ -%D \type {\unicodescale} $\times$ \type {\bodyfontsize} -%D \item inserting a \type {\unicodestrut} -%D \item inserting the character (glyph) -%D \item executing some actions afterwards -%D \stopitemize -%D -%D The actions before and after placing the glyph, is up to -%D the user supplied handler. This handler (\type -%D {\handleunicodeglpyh}) must, at a certain moment, insert -%D the glyph using \type {\insertunicodeglyph} - -\def\setunicodescale#1% - {\def\unicodescale{#1}} - -\def\dosetunicodestrut#1#2% height depth - {\def\unicodestrut - {\vrule - \!!width \zeropoint - \!!height#1\strutht - \!!depth #2\strutdp - \relax}} - -\def\setunicodestrut#1#2% height depth - {\ifdim#1\strutht>\zeropoint - \dosetunicodestrut{#1}{#2}% - \else\ifdim#1\strutdp>\zeropoint - \dosetunicodestrut{#1}{#2}% - \else - \let\unicodestrut\empty - \fi\fi} - -\def\resetunicodestrut - {\let\unicodestrut\empty} - -%D The additional scaling and strut default to: - -\setunicodescale{1} -\setunicodestrut{1}{1} - -%D But better is not to have a strut added by default: - -\resetunicodestrut - -%D The actual code for the additional actions as well as -%D specific spacing is handled outside these routines. The -%D character after the two that are under treatment is -%D available in \type {\nextutoken}. - -%D \macros -%D {defineunicodefont, setupunicodefont} -%D -%D Apart from this rather low level implementation, we also -%D provide a more user friendly alternative. Given that one -%D has defined: -%D -%D \starttyping -%D \defineunicodefont -%D [SimChi] [SimplifiedChinese] -%D [\c!scale=0.85, -%D \c!height=1.25, -%D \c!depth=1.00, -%D \c!interlinespaceinterlinie=yes, -%D \c!conversion=\chinesenumber, -%D \c!command=\handlechineseunicodeglyph] -%D \stoptyping -%D -%D Together with: -%D -%D \starttyping -%D \definefontsynonym [SimplifiedChineseRegular] [gbsong] -%D \definefontsynonym [SimplifiedChineseSlanted] [gbsongsl] -%D \stoptyping -%D -%D we can now switch to Simplified Chinese by saying \type -%D {SimChi}. Some values can be changed afterwards with -%D -%D \starttyping -%D \setupunicodefont[SimChi][...=...] -%D \stoptyping -%D -%D Specific initializations can be assigned to \type -%D {commands}. - -\def\defineunicodefont - {\dotripleempty\dodefineunicodefont} - -\def\dodefineunicodefont[#1][#2][#3]% - {\doifassignmentelse{#3} - {\setupunicodefont[#1][#3]} - {\doifelsenothing{#3} - {\setupunicodefont[#1][#3]} - {\copyparameters - [\??uc#1][\??uc#3] - [\c!height,\c!depth,\c!scale,\c!commands,\c!strut, - \c!interlinespace,\c!command,\c!conversion]}}% - \doifelsenothing{#2} - {\setvalue{#1}{[uc font #1 undefined]}} - {\setvalue{\??uc#1\c!file}{#2}% - \doifundefined{\??ff#2\s!Bold} - {\definefontsynonym[#2\s!Bold] [#2\s!Regular]% - \definefontsynonym[#2\s!Slanted] [#2\s!Regular]% - \definefontsynonym[#2\s!Italic] [#2\s!Regular]% - \definefontsynonym[#2\s!BoldSlanted][#2\s!Slanted]% - \definefontsynonym[#2\s!BoldItalic] [#2\s!Italic]}% - \unexpanded\setvalue{#1}{\enableunicodefont{#1}}}} - -\def\setupunicodefont - {\dodoubleempty\dosetupunicodefont} - -\def\dosetupunicodefont[#1][#2]% also predefines - {\doifundefined{\??uc#1\c!command} - {\copyparameters - [\??uc#1][\??uc\s!default] - [\c!height,\c!depth,\c!scale,\c!commands,\v!strut, - \c!interlinespace,\c!command,\c!conversion]}% - \getparameters[\??uc#1][#2]} - -\def\enableunicodefont#1% - {\definefontsynonym[\s!Unicode][\getvalue{\??uc#1\c!file}]% - \def\unicodescale {\getvalue{\??uc#1\c!scale}}% - \def\unicodeheight {\getvalue{\??uc#1\c!height}}% - \def\unicodedepth {\getvalue{\??uc#1\c!depth}}% - \def\unicodedigits {\getvalue{\??uc#1\c!conversion}}% - \def\handleunicodeglyph {\getvalue{\??uc#1\c!command}}% - \doifnot\currentregime{utf}{\enableregime[unicode]}% - % the following \relax's are realy needed - \doifvalue{\??uc#1\c!interlinespace}\v!yes - \setupinterlinespace\relax - \doifelsevalue{\??uc#1\c!strut}\v!yes - {\setunicodestrut\unicodeheight\unicodedepth} - {\resetunicodestrut}% - \getvalue{\??uc#1\c!commands}\relax} - -%D \macros -%D {unicodedigits} -%D -%D For convenience we also predefine a number conversion -%D macro: - -\let\unicodedigits\number - -%D Because we cannot be sure of the pressence of all font -%D styles, we remap some by default. - -\definefontsynonym [\s!Unicode\s!Bold] [\s!Unicode\s!Regular] -\definefontsynonym [\s!Unicode\s!Slanted] [\s!Unicode\s!Regular] -\definefontsynonym [\s!Unicode\s!Italic] [\s!Unicode\s!Regular] -\definefontsynonym [\s!Unicode\s!BoldSlanted] [\s!Unicode\s!Slanted] -\definefontsynonym [\s!Unicode\s!BoldItalic] [\s!Unicode\s!Italic] - -\setupunicodefont - [\s!default] - [\c!height=1, - \c!depth=1, - \c!scale=1, - \c!strut=\v!no, - \c!interlinespace=\v!no, - \c!command=\insertunicodeglyph, - \c!conversion=\number] - -\protect \endinput diff --git a/tex/context/base/font-unk.mkii b/tex/context/base/font-unk.mkii new file mode 100644 index 000000000..30f824781 --- /dev/null +++ b/tex/context/base/font-unk.mkii @@ -0,0 +1,187 @@ +%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] +\definefontsynonym [MathExtensionBold] [MathExtension] +\definefontsynonym [MathItalicBold] [MathItalic] +\definefontsynonym [MathSymbolBold] [MathSymbol] +\definefontsynonym [MathAlphaBold] [MathAlpha] +\definefontsynonym [MathBetaBold] [MathBeta] +\definefontsynonym [MathGammaBold] [MathGamma] +\definefontsynonym [MathDeltaBold] [MathDelta] + +\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). + +% \def\setfontsynonym[#1]#2[#3]{\setvalue{\??ff\fontclass#1}{#3}} +% +% \setfontsynonym[\s!Normal] [\fontstringD] +% \setfontsynonym[\s!Bold] [\fontstringD\s!Bold] +% \setfontsynonym[\s!Italic] [\fontstringD\s!Italic] +% \setfontsynonym[\s!Slanted] [\fontstringD\s!Slanted] +% \setfontsynonym[\s!BoldItalic] [\fontstringD\s!BoldItalic] +% \setfontsynonym[\s!BoldSlanted][\fontstringD\s!BoldSlanted] +% \setfontsynonym[\s!Caps] [\fontstringD\s!Caps] + +\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, + ex=MathExtension mo 1, + mi=MathItalic mo 1, + sy=MathSymbol mo 1, + nn=MathNoName mo 1, + ma=MathAlpha mo 1, + mb=MathBeta mo 1, + mc=MathGamma mo 1, + md=MathDelta mo 1] + +\definebodyfont [bfmath] [mm] + [mrbf=MathRomanBold mo 1, + exbf=MathExtensionBold mo 1, + mibf=MathItalicBold mo 1, + sybf=MathSymbolBold mo 1, + mabf=MathAlphaBold mo 1, + mbbf=MathBetaBold mo 1, + mcbf=MathGammaBold mo 1, + mdbf=MathDeltaBold 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-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-unk.tex b/tex/context/base/font-unk.tex deleted file mode 100644 index 4e450ae74..000000000 --- a/tex/context/base/font-unk.tex +++ /dev/null @@ -1,185 +0,0 @@ -%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. - -\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] -\definefontsynonym [MathExtensionBold] [MathExtension] -\definefontsynonym [MathItalicBold] [MathItalic] -\definefontsynonym [MathSymbolBold] [MathSymbol] -\definefontsynonym [MathAlphaBold] [MathAlpha] -\definefontsynonym [MathBetaBold] [MathBeta] -\definefontsynonym [MathGammaBold] [MathGamma] -\definefontsynonym [MathDeltaBold] [MathDelta] - -\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). - -% \def\setfontsynonym[#1]#2[#3]{\setvalue{\??ff\fontclass#1}{#3}} -% -% \setfontsynonym[\s!Normal] [\fontstringD] -% \setfontsynonym[\s!Bold] [\fontstringD\s!Bold] -% \setfontsynonym[\s!Italic] [\fontstringD\s!Italic] -% \setfontsynonym[\s!Slanted] [\fontstringD\s!Slanted] -% \setfontsynonym[\s!BoldItalic] [\fontstringD\s!BoldItalic] -% \setfontsynonym[\s!BoldSlanted][\fontstringD\s!BoldSlanted] -% \setfontsynonym[\s!Caps] [\fontstringD\s!Caps] - -\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, - ex=MathExtension mo 1, - mi=MathItalic mo 1, - sy=MathSymbol mo 1, - nn=MathNoName mo 1, - ma=MathAlpha mo 1, - mb=MathBeta mo 1, - mc=MathGamma mo 1, - md=MathDelta mo 1] - -\definebodyfont [bfmath] [mm] - [mrbf=MathRomanBold mo 1, - exbf=MathExtensionBold mo 1, - mibf=MathItalicBold mo 1, - sybf=MathSymbolBold mo 1, - mabf=MathAlphaBold mo 1, - mbbf=MathBetaBold mo 1, - mcbf=MathGammaBold mo 1, - mdbf=MathDeltaBold 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). - -\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-- +

Choosing a font by name and specififying its size is only part of the +game. In order to prevent complex commands, 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.

+ +

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.

+ +

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.

+--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.mkii b/tex/context/base/java-ini.mkii new file mode 100644 index 000000000..e929da108 --- /dev/null +++ b/tex/context/base/java-ini.mkii @@ -0,0 +1,713 @@ +%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: + +% 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 +%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; j0) && (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} + +\prependtoks \flushJSpreamble \to \everyshipout +\prependtoks \finalflushJSpreamble \to \everylastshipout + +%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}} + +\definespeciallocation{JS}#1#2% + {\iflocation + \bgroup + \bgroup + \presetJScode + \currentreferenceoperation + \currentreferencearguments + \egroup + \dohandlegoto + {#2}% + {\dostartgotoJS\buttonwidth\buttonheight\JScode}% + {\dostopgotoJS}% + \egroup + \else + {#2}% + \fi} + +%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/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; j0) && (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/java-ini.tex b/tex/context/base/java-ini.tex deleted file mode 100644 index 7dc2cfe04..000000000 --- a/tex/context/base/java-ini.tex +++ /dev/null @@ -1,742 +0,0 @@ -%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 - -% 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: - -\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 - - -%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; j0) && (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 - \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} - -\prependtoks \flushJSpreamble \to \everyshipout -\prependtoks \finalflushJSpreamble \to \everylastshipout - -%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}} - -\definespeciallocation{JS}#1#2% - {\iflocation - \bgroup - \bgroup - \presetJScode - \currentreferenceoperation - \currentreferencearguments - \egroup - \dohandlegoto - {#2}% - {\dostartgotoJS\buttonwidth\buttonheight\JScode}% - {\dostopgotoJS}% - \egroup - \else - {#2}% - \fi} - -%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.

--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.

--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--

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.

--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--

The parser used here is inspired by the variant discussed in the lua book, but @@ -38,15 +39,30 @@ optimize the code.

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-- +

This module can be used stand alone but also inside in +which case it hooks into the tracker code. Therefore we provide a few +functions that set the tracers.

+--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--

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("\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.

--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 = { ['&'] = '&', ['<'] = '<', ['>'] = '>', ['"'] = '"' } --~ 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 --~ --~ ]]) ---~ 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.mkii b/tex/context/base/lang-lab.mkii new file mode 100644 index 000000000..269ac249b --- /dev/null +++ b/tex/context/base/lang-lab.mkii @@ -0,0 +1,295 @@ +%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% +% {\ifcsname#2#1#3\endcsname +% \csname#2#1#3\endcsname \else +% \ifcsname#2#3\endcsname +% \csname#2#3\endcsname \else +% \ifcsname#2\defaultlanguage#1#3\endcsname +% \csname#2\defaultlanguage#1#3\endcsname \else +% \ifcsname#2\s!en#3\endcsname +% \csname#2\s!en#3\endcsname \else +% \ifcsname#2\s!nl#3\endcsname +% \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 ! #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 + \reporttextprefixerror{#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-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-lab.tex b/tex/context/base/lang-lab.tex deleted file mode 100644 index 664460129..000000000 --- a/tex/context/base/lang-lab.tex +++ /dev/null @@ -1,284 +0,0 @@ -%D \module -%D [ file=lang-lab, -%D version=1997.08.27, -%D title=\CONTEXT\ Language Macros, -%D subtitle=Language Head and Label Texts, -%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. - -\writestatus{loading}{Language Head and Label Texts} - -\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% -% {\ifcsname#2#1#3\endcsname -% \csname#2#1#3\endcsname \else -% \ifcsname#2#3\endcsname -% \csname#2#3\endcsname \else -% \ifcsname#2\defaultlanguage#1#3\endcsname -% \csname#2\defaultlanguage#1#3\endcsname \else -% \ifcsname#2\s!en#3\endcsname -% \csname#2\s!en#3\endcsname \else -% \ifcsname#2\s!nl#3\endcsname -% \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} - -\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]% don't group! SLOW if really used: speed up - {\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]}}}} - -\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.mkii b/tex/context/base/lang-spe.mkii new file mode 100644 index 000000000..7911b0c95 --- /dev/null +++ b/tex/context/base/lang-spe.mkii @@ -0,0 +1,244 @@ +%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. + +%D This code was originally placed in the language +%D initialization module, but isolating it is clearer. Language +%D specifics evolved out of user demands for special features, +%D like the german active quote. After a while I decided to +%D associate them to languages in a more general way so that we +%D could associate all kind of things with language switching. +%D +%D This is a typical example of functionality that occasionally +%D gets improved based on user input and experience. Much of the +%D code is pretty old and could probabbly be done in better ways. +%D It's probably also the kind of code that has been and will be +%D written over and over again by \TEX\ users around the world, +%D so there are probably better implementations of similar +%D functionality around. Therefore, users are invited to pop in +%D their own handling as long as it does not interfere with +%D existing code. Writing the more obscure macros that deal with +%D this is a good learning experience (catcodes, lccodes, token +%D lists, expansion, \unknown). + +\writestatus{loading}{ConTeXt Language Macros / Specifics} + +\unprotect + +%D \macros +%D {everyresetlanguagespecifics,resetlanguagespecifics} +%D +%D Cleanup macros. + +\newevery \everyresetlanguagespecifics \relax + +\def\resetlanguagespecifics + {\ifcase\protectionlevel + \the\everyresetlanguagespecifics + \else % to be translated + % \writestatus\m!systems{don't change language in unprotected mode!}% + \fi} + +\appendtoks + \resetlanguagespecifics +\to \everycleanupfeatures + +%D \macros +%D {startlanguagespecifics,enablelanguagespecifics} +%D +%D Each language has its own typographic pecularities. Some of +%D those can be influenced by parameters, others are handled by +%D the interface, but as soon as specific commands come into +%D view we need another mechanism. In the macro that activates +%D a language, we call \type{\enablelanguagespecifics}. This +%D macro in return calls for the setup of language specific +%D macros. Such specifics are defined as: +%D +%D \starttyping +%D \startlanguagespecifics[de] +%D \installcompoundcharacter "a {\"a} +%D \installcompoundcharacter "e {\"e} +%D \installcompoundcharacter "s {\SS} +%D \stoplanguagespecifics +%D \stoptyping +%D +%D Instead of \type{[du]} we can pass a comma separated +%D list, like \type{[du,nl]}. Next calls to this macro add the +%D specifics to the current list. +%D +%D Before we actually read the specifics, we first take some +%D precautions that will prevent spurious spaces to creep into +%D the list. + +% We should use token registers, but alas, we run out of them and +% \ETEX\ has a bug. Well, let's use a token register now (2006). + +\def\startlanguagespecifics% % we use double to + {\bgroup + \catcode`\^^I=\@@ignore + \catcode`\^^M=\@@ignore + \catcode`\^^L=\@@ignore + \dodoubleempty\dostartlanguagespecifics} % get rid of spaces + +%D The main macro looks quite complicated but actually does +%D nothing special. By embedding \type{\do} we can easily +%D append to the lists and also execute them at will. Just to +%D be sure, we check on spurious spaces. The second dummy +%D argument gobbles spaces. + +\def\languageencoding + {\ifx\characterencoding\nocharacterencoding \else + \characterencoding-% + \fi} + +\long\def\dostartlanguagespecifics[#1][#2]#3\stoplanguagespecifics + {\egroup + \processcommalist[#1]{\dosetlanguagespecifics{#3}}} + +% \long\def\dosetlanguagespecifics#1#2% +% {\ifundefined{\??la\languageencoding#2\??la}\forgetlanguagespecifics[#2]\fi +% % the next line catches the case that specifics are enabled *before* they are defined +% \expandafter\ifx\csname\??la\languageencoding#2\??la\endcsname\relax\forgetlanguagespecifics[#2]\fi +% \appendvalue{\??la\languageencoding#2\??la}{#1}% +% \bgroup +% \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}% +% \ifdim\wd\scratchbox>\zeropoint +% \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait +% \else +% \showmessage\m!linguals8{\currentencoding-#2}% +% \fi +% \egroup +% \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}} + +\def\languagespectag#1{\??la\languageencoding#1\??la} + +\long\def\dosetlanguagespecifics#1#2% + {\edef\askedlanguagespecificstag{\languagespectag{#2}}% + \ifcsname\askedlanguagespecificstag\endcsname \else + \expandafter\newtoks\csname\askedlanguagespecificstag\endcsname + \fi + \csname\askedlanguagespecificstag\endcsname\@EA{\the\csname\askedlanguagespecificstag\endcsname#1}% + \bgroup + \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}% + \ifdim\wd\scratchbox>\zeropoint + \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait + \else + \showmessage\m!linguals8{\currentencoding-#2}% + \fi + \egroup + \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}} + +\def\forgetlanguagespecifics[#1]% + {\csname\languagespectag{#1}\endcsname\emptytoks} + +%D Enabling them is rather straightforward. We only have to +%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 ? + +\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 +%D The next code makes it possible to disable the specifics. + +% \def\deactivatelanguagespecific#1% +% {\ifundefined{l g s \string#1}% +% \letgvalueempty{l g s \string#1}% signal to prevent dup def +% \bgroup +% \catcode`#1=\@@active +% \uccode`~=`#1 +% \uppercase{\doglobal\appendtoks\dodeactivatetoken{~}\to\everyresetlanguagespecifics}% +% \egroup +% \expanded{\doglobal\noexpand\appendtoks{#1}{\the\catcode`#1}}\to\everyresetlanguagespecifics +% \fi} + +% \def\dodeactivatetoken#1#2#3% test needed to avoid clash with \unprotect +% {\def#1{#2}\ifnum\catcode`#2=\@@active\catcode`#2=#3\relax\fi} + +%D We cannot hook this into the installer since language +%D specifics can be anything. So far, we have the following +%D potentially active characters. + +%D Beware, this should happen under an unprotected regime; +%D thanks to Giuseppe Oblomov Bilotta, who first noticed +%D that something was wrong. + +\protect + +% \deactivatelanguagespecific " +% \deactivatelanguagespecific / +% \deactivatelanguagespecific : +% \deactivatelanguagespecific ; +% \deactivatelanguagespecific ? +% \deactivatelanguagespecific ! + +\unprotect + +% yes or no (taco wins: no) + +% \startlanguagespecifics[nl,cs,sk,fr] +% \lccode`\'=`\' +% \stoplanguagespecifics + +%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. + +% \ifprocessingXML is a nasty dependency + +\appendtoks + \ifprocessingXML \else \resetlanguagespecifics \fi +\to \everylanguage + +\protect \endinput 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-spe.tex b/tex/context/base/lang-spe.tex deleted file mode 100644 index 00b514be2..000000000 --- a/tex/context/base/lang-spe.tex +++ /dev/null @@ -1,242 +0,0 @@ -%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. - -%D This code was originally placed in the language -%D initialization module, but isolating it is clearer. Language -%D specifics evolved out of user demands for special features, -%D like the german active quote. After a while I decided to -%D associate them to languages in a more general way so that we -%D could associate all kind of things with language switching. -%D -%D This is a typical example of functionality that occasionally -%D gets improved based on user input and experience. Much of the -%D code is pretty old and could probabbly be done in better ways. -%D It's probably also the kind of code that has been and will be -%D written over and over again by \TEX\ users around the world, -%D so there are probably better implementations of similar -%D functionality around. Therefore, users are invited to pop in -%D their own handling as long as it does not interfere with -%D existing code. Writing the more obscure macros that deal with -%D this is a good learning experience (catcodes, lccodes, token -%D lists, expansion, \unknown). - -\writestatus{loading}{Context Language Macros / Specifics} - -\unprotect - -%D \macros -%D {everyresetlanguagespecifics,resetlanguagespecifics} -%D -%D Cleanup macros. - -\newevery \everyresetlanguagespecifics \relax - -\def\resetlanguagespecifics - {\ifcase\protectionlevel - \the\everyresetlanguagespecifics - \else % to be translated - % \writestatus\m!systems{don't change language in unprotected mode!}% - \fi} - -\appendtoks - \resetlanguagespecifics -\to \everycleanupfeatures - -%D \macros -%D {startlanguagespecifics,enablelanguagespecifics} -%D -%D Each language has its own typographic pecularities. Some of -%D those can be influenced by parameters, others are handled by -%D the interface, but as soon as specific commands come into -%D view we need another mechanism. In the macro that activates -%D a language, we call \type{\enablelanguagespecifics}. This -%D macro in return calls for the setup of language specific -%D macros. Such specifics are defined as: -%D -%D \starttyping -%D \startlanguagespecifics[de] -%D \installcompoundcharacter "a {\"a} -%D \installcompoundcharacter "e {\"e} -%D \installcompoundcharacter "s {\SS} -%D \stoplanguagespecifics -%D \stoptyping -%D -%D Instead of \type{[du]} we can pass a comma separated -%D list, like \type{[du,nl]}. Next calls to this macro add the -%D specifics to the current list. -%D -%D Before we actually read the specifics, we first take some -%D precautions that will prevent spurious spaces to creep into -%D the list. - -% We should use token registers, but alas, we run out of them and -% \ETEX\ has a bug. Well, let's use a token register now (2006). - -\def\startlanguagespecifics% % we use double to - {\bgroup - \catcode`\^^I=\@@ignore - \catcode`\^^M=\@@ignore - \catcode`\^^L=\@@ignore - \dodoubleempty\dostartlanguagespecifics} % get rid of spaces - -%D The main macro looks quite complicated but actually does -%D nothing special. By embedding \type{\do} we can easily -%D append to the lists and also execute them at will. Just to -%D be sure, we check on spurious spaces. The second dummy -%D argument gobbles spaces. - -\def\languageencoding - {\ifx\characterencoding\nocharacterencoding \else - \characterencoding-% - \fi} - -\long\def\dostartlanguagespecifics[#1][#2]#3\stoplanguagespecifics - {\egroup - \processcommalist[#1]{\dosetlanguagespecifics{#3}}} - -% \long\def\dosetlanguagespecifics#1#2% -% {\ifundefined{\??la\languageencoding#2\??la}\forgetlanguagespecifics[#2]\fi -% % the next line catches the case that specifics are enabled *before* they are defined -% \expandafter\ifx\csname\??la\languageencoding#2\??la\endcsname\relax\forgetlanguagespecifics[#2]\fi -% \appendvalue{\??la\languageencoding#2\??la}{#1}% -% \bgroup -% \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}% -% \ifdim\wd\scratchbox>\zeropoint -% \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait -% \else -% \showmessage\m!linguals8{\currentencoding-#2}% -% \fi -% \egroup -% \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}} - -\def\languagespectag#1{\??la\languageencoding#1\??la} - -\long\def\dosetlanguagespecifics#1#2% - {\ifcsname\languagespectag{#2}\endcsname \else - \expandafter\newtoks\csname\languagespectag{#2}\endcsname - \fi - \csname\languagespectag{#2}\endcsname\@EA{\the\csname\languagespectag{#2}\endcsname#1}% - \bgroup - \setbox\scratchbox\hbox{\enablelanguagespecifics[#2]}% - \ifdim\wd\scratchbox>\zeropoint - \showmessage\m!linguals7{\currentencoding-#2,\the\wd\scratchbox\space}\wait - \else - \showmessage\m!linguals8{\currentencoding-#2}% - \fi - \egroup - \doif{#2}\currentmainlanguage{\enablelanguagespecifics[#2]}} - -% \def\forgetlanguagespecifics[#1]% -% {\letvalue{\??la\languageencoding#1\??la}\empty} - -\def\forgetlanguagespecifics[#1]% - {\csname\languagespectag{#1}\endcsname\emptytoks} - -%D Enabling them is rather straightforward. We only have to -%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#1\??la}\emptytoks -% \the\executeifdefined{\??la\languageencoding#1\??la}\emptytoks} % dup ? - -%D \macros -%D {deactivatelanguagespecific} -%D -%D The next code makes it possible to disable the specifics. - -% \def\deactivatelanguagespecific#1% -% {\ifundefined{l g s \string#1}% -% \letgvalueempty{l g s \string#1}% signal to prevent dup def -% \bgroup -% \catcode`#1=\@@active -% \uccode`~=`#1 -% \uppercase{\doglobal\appendtoks\dodeactivatetoken{~}\to\everyresetlanguagespecifics}% -% \egroup -% \expanded{\doglobal\noexpand\appendtoks{#1}{\the\catcode`#1}}\to\everyresetlanguagespecifics -% \fi} - -% \def\dodeactivatetoken#1#2#3% test needed to avoid clash with \unprotect -% {\def#1{#2}\ifnum\catcode`#2=\@@active\catcode`#2=#3\relax\fi} - -%D We cannot hook this into the installer since language -%D specifics can be anything. So far, we have the following -%D potentially active characters. - -%D Beware, this should happen under an unprotected regime; -%D thanks to Giuseppe Oblomov Bilotta, who first noticed -%D that something was wrong. - -\protect - -% \deactivatelanguagespecific " -% \deactivatelanguagespecific / -% \deactivatelanguagespecific : -% \deactivatelanguagespecific ; -% \deactivatelanguagespecific ? -% \deactivatelanguagespecific ! - -\unprotect - -% yes or no (taco wins: no) - -% \startlanguagespecifics[nl,cs,sk,fr] -% \lccode`\'=`\' -% \stoplanguagespecifics - -%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. - -% \ifprocessingXML is a nasty dependency - -\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--

Callbacks are the real asset of . They permit you to hook your own code into the engine. Here we implement a few handy @@ -67,7 +69,6 @@ end)

This does a one-shot.

--ldx]]-- - --[[ldx--

Callbacks may result in 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.

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-deb.lua b/tex/context/base/luat-deb.lua deleted file mode 100644 index a32d923bd..000000000 --- a/tex/context/base/luat-deb.lua +++ /dev/null @@ -1,154 +0,0 @@ --- 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 versions then versions = { } end versions['luat-deb'] = 1.001 -if not lmx then lmx = { } end -if not lmx.variables then lmx.variables = { } end - -lmx.variables['color-background-green'] = '#4F6F6F' -lmx.variables['color-background-blue'] = '#6F6F8F' -lmx.variables['color-background-yellow'] = '#8F8F6F' -lmx.variables['color-background-purple'] = '#8F6F8F' - -lmx.variables['color-background-body'] = '#808080' -lmx.variables['color-background-main'] = '#3F3F3F' -lmx.variables['color-background-one'] = lmx.variables['color-background-green'] -lmx.variables['color-background-two'] = lmx.variables['color-background-blue'] - -lmx.variables['title-default'] = 'ConTeXt Status Information' -lmx.variables['title'] = lmx.variables['title-default'] - -if not tracers then tracers = { } end -if not tracers.list then tracers.list = { } end -if not tracers.strings then tracers.strings = { } end - -tracers.strings.undefined = "undefined" - -function tracers.split(csname) - return csname:match("^(.+):(.+)$") -end - -function tracers.type(csname) - tag, name = tracers.split(csname) - if tag then return tag else return nil end -end - -function tracers.name(csname) - tag, name = tracers.split(csname) - if tag then return name else return csname end -end - -function tracers.cs(csname) - tag, name = tracers.split(csname) - if tracers.types[tag] then - return tracers.types[tag](name) - else - return tracers.primitive(csname) - end -end - -function tracers.dimen(name) - return (tex.dimen[name] and number.topoints(tex.dimen[name])) or tracers.strings.undefined -end - -function tracers.count(name) - return tex.count[name] or tracers.strings.undefined -end - -function tracers.toks(name) - return (tex.toks[name] and string.limit(tex.toks[name],40)) or tracers.strings.undefined -end - -function tracers.primitive(name) - return tex[name] or tracers.strings.undefined -end - -tracers.types = { - ['d'] = tracers.dimen, - ['c'] = tracers.count, - ['t'] = tracers.toks, - ['p'] = tracers.primitive -} - -function tracers.knownlist(name) - return tracers.list[name] and #tracers.list[name] > 0 -end - -function tracers.showdebuginfo() - lmx.set('title', 'ConTeXt Debug Information') - lmx.set('color-background-one', lmx.get('color-background-green')) - lmx.set('color-background-two', lmx.get('color-background-blue')) - lmx.show('context-debug.lmx') - lmx.restore() -end - -function tracers.showerror() - lmx.set('title', 'ConTeXt Error Information') - lmx.set('errormessage', status.lasterrorstring) - lmx.set('linenumber', status.linenumber) - lmx.set('color-background-one', lmx.get('color-background-yellow')) - lmx.set('color-background-two', lmx.get('color-background-purple')) - local filename = status.filename - local linenumber = tonumber(status.linenumber or "0") - if not filename then - lmx.set('filename', 'unknown') - lmx.set('errorcontext', 'error in filename') - elseif type(filename) == "number" then - lmx.set('filename', "") - lmx.set('errorcontext', 'unknown error') - elseif io.exists(filename) then - -- todo: use an input opener so that we also catch utf16 an reencoding - lmx.set('filename', filename) - lines = io.lines(filename) - if lines then - local context = { } - n, m = 1, linenumber - b, e = m-10, m+10 - s = string.len(tostring(e)) - for line in lines do - if n > e then - break - elseif n > b then - if n == m then - context[#context+1] = string.format("%" .. s .. "d",n) .. " >> " .. line - else - context[#context+1] = string.format("%" .. s .. "d",n) .. " " .. line - end - end - n = n + 1 - end - lmx.set('errorcontext', table.concat(context,"\n")) - else - lmx.set('errorcontext', "") - end - else - lmx.set('filename', filename) - lmx.set('errorcontext', 'file not found') - end - lmx.show('context-error.lmx') - lmx.restore() -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 - -tracers.list['scratch'] = { - 0, 2, 4, 6, 8 -} - -tracers.list['internals'] = { - 'p:hsize', 'p:parindent', 'p:leftskip','p:rightskip', - 'p:vsize', 'p:parskip', 'p:baselineskip', 'p:lineskip', 'p:topskip' -} - -tracers.list['context'] = { - 'd:lineheight', - 'c:realpageno', 'c:pageno', 'c:subpageno' -} diff --git a/tex/context/base/luat-deb.tex b/tex/context/base/luat-deb.tex deleted file mode 100644 index 55686ac11..000000000 --- a/tex/context/base/luat-deb.tex +++ /dev/null @@ -1,49 +0,0 @@ -%D \module -%D [ file=luat-deb, -%D version=2005.11.06, -%D title=\CONTEXT\ Communication 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}{Communication Support (initialization)} - -\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 - -\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 - debugger.enable() ; - end - }% -\to \everyjob - -\appendtoks - \ctxlua { - if debugger.tracing() then - debugger.disable() ; - debugger.savestats("\jobname-luacalls.log") ; - end - }% -\to \everybye - -\endinput 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--

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.

--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-- +

These can be used/set by the caller program; mtx-context.lua does it.

+--ldx]]-- + +document.arguments = document.arguments or { } +document.files = document.files or { } --[[ldx--

Please create a namespace within these tables before using them!

@@ -24,3 +34,116 @@ userdata ['my.name'] = { } thirddata['tricks' ] = { } --ldx]]-- + +--[[ldx-- +

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.

+--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{} 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("\n") - f:write("\n") - if jobname then - f:write("\t" .. jobname .. "\n") - end - f:write("\t\n") - for _,v in pairs(sorted(instance.foundintrees)) do -- ipairs - f:write("\t\t" .. v .. "\n") - end - f:write("\t\n") - f:write("\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-- -

This file is used when we want the input handlers to behave like -kpsewhich. What to do with the following:

- - -{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} -$SELFAUTOLOC : /usr/tex/bin/platform -$SELFAUTODIR : /usr/tex/bin -$SELFAUTOPARENT : /usr/tex - - -

How about just forgetting abou them?

---ldx]]-- - -input = input or { } -input.suffixes = input.suffixes or { } -input.formats = input.formats or { } - -input.suffixes['gf'] = { 'gf' } -input.suffixes['pk'] = { '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-- -

If you wondered abou tsome of the previous mappings, how about -the next bunch:

---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 {#1}} @@ -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-lmx.lua b/tex/context/base/luat-lmx.lua deleted file mode 100644 index b9bab7df1..000000000 --- a/tex/context/base/luat-lmx.lua +++ /dev/null @@ -1,141 +0,0 @@ --- 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 versions then versions = { } end versions['luat-mlx'] = 1.001 - --- we can now use l-xml, and we can also use lpeg - -lmx = { } - -lmx.escapes = { - ['&'] = '&', - ['<'] = '<', - ['>'] = '>', - ['"'] = '"' -} - --- local function p -> ends up in lmx.p, so we need to cast - -lmx.variables = { } - -lmx.variables['title-default'] = 'LMX File' -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) -end - -lmx.converting = false - -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 - end - function lmx.variable(str) - return lmx.variables[str] or "" - end - function lmx.escape(str) - return string.gsub(str:gsub('&','&'),'[<>"]',lmx.escapes) - end - function lmx.type(str) - if str then lmx.print("" .. lmx.escape(str) .. "") end - end - function lmx.pv(str) - lmx.print(lmx.variable(str)) - end - function lmx.tv(str) - lmx.type(lmx.variable(str)) - end - data = data:gsub("<%?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) - definitions[tag] = content - return "" - end) - data = data:gsub("<%?lmx%-resolve%s+(%S-)%s-%?>", function(tag) - return definitions[tag] or "" - end) - data = data:gsub("%c%s-(<%?lua .-%?>)%s-%c", function(lua) - return "\n" .. lua .. " " - end) - data = string.gsub(data .. "","(.-)<%?lua%s+(.-)%?>", function(txt, lua) - txt = txt:gsub("%c+", "\\n") - txt = txt:gsub('"' , '\\"') - txt = txt:gsub("'" , "\\'") - -- txt = string.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() - 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 - -if os.platform == "windows" then - lmx.popupfile = function(filename) os.execute("start " .. filename) end -else - lmx.popupfile = function(filename) os.execute(filename) end -end - -function lmx.show(name) - local lmxfile = lmx.lmxfile(name) - local htmfile = lmx.htmfile(name) - if lmxfile == htmfile then - htmfile = string.gsub(lmxfile, "%.%a+$", "html") - end - lmx.convert(lmxfile, htmfile) - lmx.popupfile(htmfile) -end - --- kind of private - -lmx.restorables = { } - -function lmx.set(key, value) - if not lmx.restorables[key] then - table.insert(lmx.restorables, key) - lmx.variables['@@' .. key] = lmx.variables[key] - end - lmx.variables[key] = value -end - -function lmx.get(key) - return lmx.variables[key] or "" -end - -function lmx.restore() - for _,key in pairs(lmx.restorables) do - lmx.variables[key] = lmx.variables['@@' .. key] - end - lmx.restorables = { } -end - --- command line - -if arg then - if arg[1] == "--show" then if arg[2] then lmx.show (arg[2]) end - elseif arg[1] == "--convert" then if arg[2] then lmx.convert(arg[2], arg[3] or "temp.html") end - end -end diff --git a/tex/context/base/luat-lmx.tex b/tex/context/base/luat-lmx.tex deleted file mode 100644 index cc7fa448f..000000000 --- a/tex/context/base/luat-lmx.tex +++ /dev/null @@ -1,16 +0,0 @@ -%D \module -%D [ file=luat-lmx, -%D version=2005.09.02, -%D title=\CONTEXT\ Lua Macros, -%D subtitle=LMX 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 (lmx)} - -\registerctxluafile{luat-lmx}{1.001} 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-- -

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 structured file. Actually, any logging that -is hooked into callbacks will be \XML\ by default.

---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-- -

This looks pretty ugly but we need to speed things up a bit.

---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("%s",category,format(fmt,...))) -end -function logs.xml.line(fmt,...) -- new - write_nl(format("%s",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("") end end -function logs.xml.push () 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("

") - write_nl("") -end - -function logs.xml.report_output_pages(p,b) - write_nl(format("", p)) - write_nl(format("", 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: - 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("") - end - function input.show_close(name) - texio.write(" ") - input.level = input.level - 1 - end - function input.show_load(name) - texio.write_nl("") -- 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("callback "..k.." is not set") 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("

") - 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(""..p.."") - texio.write_nl(""..b.."") - 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("") - texio.write_nl("") - texio.write_nl("") - end - function input.stop_run() - texio.write_nl("") - end - function input.show_statistics() - for k,v in pairs(status.list()) do - texio.write_nl("log",""..tostring(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-- -

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.

- - -TEXMFCACHE=$TMP;$TEMP;$TMPDIR;$TEMPDIR;$HOME;$TEXMFVAR;$VARTEXMF;. - - -

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.

---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-- -

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).

- -

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.

- -

Examples of usage can be found in the font related code.

---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-tra.lua b/tex/context/base/luat-tra.lua deleted file mode 100644 index 5314b48c6..000000000 --- a/tex/context/base/luat-tra.lua +++ /dev/null @@ -1,145 +0,0 @@ --- 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 - --- the 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 = { } - -local counters = { } -local names = { } -local getinfo = debug.getinfo -local format = string.format - --- one - -local function hook() - local f = getinfo(2,"f").func - local n = getinfo(2,"Sn") --- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end - if f then - local cf = counters[f] - if cf == nil then - counters[f] = 1 - names[f] = n - else - counters[f] = cf + 1 - end - end -end -local function getname(func) - local n = names[func] - if n then - if n.what == "C" then - return n.name or '' - else - -- source short_src linedefined what name namewhat nups func - local name = n.name or n.namewhat or n.what - if not name or name == "" then name = "?" end - return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) - end - else - return "unknown" - end -end -function debugger.showstats(printer,threshold) - printer = printer or texio.write or print - threshold = threshold or 0 - local total, grandtotal, functions = 0, 0, 0 - printer("\n") -- ugly but ok - -- table.sort(counters) - for func, count in pairs(counters) do - if count > threshold then - local name = getname(func) - if not name:find("for generator") then - printer(format("%8i %s", count, name)) - total = total + count - end - end - grandtotal = grandtotal + count - functions = functions + 1 - end - printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) -end - --- two - ---~ local function hook() ---~ local n = getinfo(2) ---~ if n.what=="C" and not n.name then ---~ local f = tostring(debug.traceback()) ---~ local cf = counters[f] ---~ if cf == nil then ---~ counters[f] = 1 ---~ names[f] = n ---~ else ---~ counters[f] = cf + 1 ---~ end ---~ end ---~ end ---~ function debugger.showstats(printer,threshold) ---~ printer = printer or texio.write or print ---~ threshold = threshold or 0 ---~ local total, grandtotal, functions = 0, 0, 0 ---~ printer("\n") -- ugly but ok ---~ -- table.sort(counters) ---~ for func, count in pairs(counters) do ---~ if count > threshold then ---~ printer(format("%8i %s", count, func)) ---~ total = total + count ---~ end ---~ grandtotal = grandtotal + count ---~ functions = functions + 1 ---~ end ---~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) ---~ end - --- rest - -function debugger.savestats(filename,threshold) - local f = io.open(filename,'w') - if f then - debugger.showstats(function(str) f:write(str) end,threshold) - f:close() - end -end - -function debugger.enable() - debug.sethook(hook,"c") -end - -function debugger.disable() - debug.sethook() ---~ counters[debug.getinfo(2,"f").func] = nil -end - -function debugger.tracing() - local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 - if n > 0 then - function debugger.tracing() return true end ; return true - else - function debugger.tracing() return false end ; return false - end -end - ---~ debugger.enable() - ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) ---~ print(math.sin(1*.5)) - ---~ debugger.disable() - ---~ print("") ---~ debugger.showstats() ---~ print("") ---~ debugger.showstats(print,3) - 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-- +

We provide (at least here) two entity handlers. The more extensive +resolver consults a hash first, tries to convert to next, +and finaly calls a handler when defines. When this all fails, the +original entity is returned.

+--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 +--~ +--~ +--~ +--~ +--~ +--~ +--~ + +lxml.directives = { } + +local data = { + setup = { }, + before = { }, + after = { } +} - --~ - --~ - --~ - --~ - --~ - --~ - --~ - - 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("",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 - 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 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-- +

The following helper functions best belong to the lmxl-ini +module. Some are here because we need then in the mk +document and other manuals, others came up when playing with +this module. Since this module is also used in we've +put them here instead of loading mode modules there then needed.

+--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 = { ['&'] = '&', ['<'] = '<', ['>'] = '>', ['"'] = '"' } +--~ 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("<")/"<" + S(">")/">" + S("&")/"&" + 1)^0) +local normal = (1 - S("<&>"))^0 +local special = P("<")/"<" + P(">")/">" + P("&")/"&" +local escaped = Cs(normal * (special * normal)^0) + +-- 100 * 1000 * "oeps< oeps> oeps&" : gsub:lpeg == 0153:0280:0151:0080 (last one by roberto) + +-- unescaped = Cs((S("<")/"<" + S(">")/">" + S("&")/"&" + 1)^0) +-- unescaped = Cs((((P("&")/"") * (P("lt")/"<" + P("gt")/">" + P("amp")/"&") * (P(";")/"")) + 1)^0) +local normal = (1 - S"&")^0 +local special = P("<")/"<" + P(">")/">" + P("&")/"&" +local unescaped = Cs(normal * (special * normal)^0) + +-- 100 * 5000 * "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-- +

This module can be used stand alone but also inside 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.

+--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-- +

We've now arrived at an intersting part: accessing the tree using a subset +of and since we're not compatible we call it . We +will explain more about its usage in other documents.

+--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("\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-- +

An 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:

+ + +r : the root element of the data table +d : the data table of the result +t : the index in the data table of the result + + +

Access to the root and data table makes it possible to construct insert and delete +functions.

+--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-- +

Next come all kind of locators and manipulators. The most generic function here +is xml.filter(root,pattern). All registers functions in the filters namespace +can be path of a search path, as in:

+ + +local r, d, k = xml.filter(root,"/a/b/c/position(4)" + +--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-- +

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.

+--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-- +

The following functions collect elements and texts.

+--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-- +

Often using an iterators looks nicer in the code than passing handler +functions. The book describes how to use coroutines for that +purpose (). This permits +code like:

+ + +for r, d, k in xml.elements(xml.load('text.xml'),"title") do + print(d[k]) +end + + +

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:

+ + +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 + + +

We use the function variants in the filters.

+--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-- +

We've now arrives at the functions that manipulate the tree.

+--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-- +

Here are a few synonyms.

+--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-- +

The following helper functions best belong to the lmxl-ini +module. Some are here because we need then in the mk +document and other manuals, others came up when playing with +this module. Since this module is also used in we've +put them here instead of loading mode modules there then needed.

+--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 = { ['&'] = '&', ['<'] = '<', ['>'] = '>', ['"'] = '"' } +--~ 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("<")/"<" + S(">")/">" + S("&")/"&" + 1)^0) +local normal = (1 - S("<&>"))^0 +local special = P("<")/"<" + P(">")/">" + P("&")/"&" +local escaped = Cs(normal * (special * normal)^0) + +-- 100 * 1000 * "oeps< oeps> oeps&" : gsub:lpeg == 0153:0280:0151:0080 (last one by roberto) + +-- unescaped = Cs((S("<")/"<" + S(">")/">" + S("&")/"&" + 1)^0) +-- unescaped = Cs((((P("&")/"") * (P("lt")/"<" + P("gt")/">" + P("amp")/"&") * (P(";")/"")) + 1)^0) +local normal = (1 - S"&")^0 +local special = P("<")/"<" + P(">")/">" + P("&")/"&" +local unescaped = Cs(normal * (special * normal)^0) + +-- 100 * 5000 * "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([[ +--~ +--~ 01 +--~ 02 +--~ 03 +--~ OK +--~ 05 +--~ 06 +--~ ALSO OK +--~ +--~ ]]) + +--~ 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 = [[ +--~ +--~ +--~ my secret +--~ +--~ ]] + +--~ x = xml.convert([[ +--~ 0102xx03OK +--~ ]]) +--~ 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-- +

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 based one. +The find based parser can be found in l-xml-edu.lua along with other older code.

+ +

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 we also need +this module for process management, like handling and +files.

+ + +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) + + +

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.

+--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-- +

This module can be used stand alone but also inside in +which case it hooks into the tracker code. Therefore we provide a few +functions that set the tracers.

+--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-- +

First a hack to enable namespace resolving. A namespace is characterized by +a . The following function associates a namespace prefix with a +pattern. We use , 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.

+--ldx]]-- + +xml.xmlns = xml.xmlns or { } + +local check = lpeg.P(false) +local parse = check + +--[[ldx-- +

The next function associates a namespace prefix with an . This +normally happens independent of parsing.

+ + +xml.registerns("mml","mathml") + +--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-- +

The next function also registers a namespace, but this time we map a +given namespace prefix onto a registered one, using the given +. This used for attributes like xmlns:m.

+ + +xml.checkns("m","http://www.w3.org/mathml") + +--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-- +

Next we provide a way to turn an into a registered +namespace. This used for the xmlns attribute.

+ + +resolvedns = xml.resolvens("http://www.w3.org/mathml") + + +This returns mml. +--ldx]]-- + +function xml.resolvens(url) + return parse:match(lower(url)) or "" +end + +--[[ldx-- +

A namespace in an element can be remapped onto the registered +one efficiently by using the xml.xmlns table.

+--ldx]]-- + +--[[ldx-- +

This version uses . 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 files that +took 12.5 seconds to load (1.5 for file io and the rest for tree building). With +the implementation we got that down to less 7.3 seconds. Loading the 14 + interface definition files (2.6 meg) went down from 1.05 seconds to 0.55.

+ +

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 + code to it.

+ + + + + + + + + + +

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:

+ + +local x = xml.convert(somestring) + + +

An optional second boolean argument tells this function not to create a root +element.

+--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("Packaging data in an xml like table is done with the following +function. Maybe it will go away (when not used).

+--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-- +

We cannot load an from a filehandle so we need to load +the whole file first. The function accepts a string representing +a filename or a file handle.

+--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-- +

When we inject new elements, we need to convert strings to +valid trees, which is what the next function does.

+--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-- +

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!

+--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-- +

In 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.

+--ldx]]-- + +-- todo: add 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("",edt[1])) + handle("") + elseif etg == "@cm@" then + -- handle(format("",edt[1])) + handle("") + elseif etg == "@cd@" then + -- handle(format("",edt[1])) + handle("") + elseif etg == "@dt@" then + -- handle(format("",edt[1])) + handle("") + 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("",ens,etg)) + handle("") + 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("",etg)) + handle("") + 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-- +

At the cost of some 25% runtime overhead you can first convert the tree to a string +and then handle the lot.

+--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-- +

The next function operated on the content only and needs a handle function +that accepts a string.

+--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-- +

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):

+ + +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 + + +

The save function is given below.

+--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-- +

A few helpers:

+--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-- +

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:

+ + +dt[k] = xml.empty() or xml.empty(dt,k) + +--ldx]]-- + +function xml.empty(dt,k) + if dt and k then + dt[k] = "" + return dt[k] + else + return "" + end +end + +--[[ldx-- +

The next helper assigns a tree (or string). Usage:

+ + +dt[k] = xml.assign(root) or xml.assign(dt,k,root) + +--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-arr.mkiv b/tex/context/base/math-arr.mkiv new file mode 100644 index 000000000..5c6cfc294 --- /dev/null +++ b/tex/context/base/math-arr.mkiv @@ -0,0 +1,439 @@ +%D \module +%D [ file=math-arr, +%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? + +\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 + +%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-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", "" }, + }, + ['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[""] = 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-ext.tex b/tex/context/base/math-ext.tex deleted file mode 100644 index cf332ba00..000000000 --- a/tex/context/base/math-ext.tex +++ /dev/null @@ -1,437 +0,0 @@ -%D \module -%D [ file=math-ext, -%D version=2007.07.19, -%D title=\CONTEXT\ Math Macros, -%D subtitle=Extra Macros, -%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. - -\unprotect - -%D These will be generalized! - -\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 - -%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}% - $\m@th\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 - $\m@th\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-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-- -

Math definitions. This code may move.

---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-- +

Remapping mathematics alphabets.

+--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.mkii b/tex/context/base/math-pln.mkii new file mode 100644 index 000000000..0bacc40a2 --- /dev/null +++ b/tex/context/base/math-pln.mkii @@ -0,0 +1,360 @@ +%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 / 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. + +% \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\undefined \let\displ@y\relax\fi + +\newbox\rootbox + +\def\root#1\of + {\setbox\rootbox\hbox{$\mathsurround\zeropoint\scriptscriptstyle{#1}$}% + \mathpalette\r@@t} + +\def\r@@t#1#2% will be overloaded + {\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\mathhexbox#1#2#3% + {\leavevmode + \hbox{$\mathsurround\zeropoint\mathchar"#1#2#3$}} + +\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-$} + +% must go to math-tex + +\ifx\braceld\undefined + % mkii values + \mathchardef\braceld="37A + \mathchardef\bracerd="37B + \mathchardef\bracelu="37C + \mathchardef\braceru="37D +\fi + +\def\downbracefill + {$\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 + {$\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 + +\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\overrightarrow#1% + {\vbox{\mathsurround\zeropoint\ialign{##\crcr + \rightarrowfill\crcr\noalign{\kern-\onepoint\nointerlineskip} + $\hfil\displaystyle{#1}\hfil$\crcr}}} + +\def\overleftarrow#1% + {\vbox{\mathsurround\zeropoint\ialign{##\crcr + \leftarrowfill\crcr\noalign{\kern-\onepoint\nointerlineskip} + $\hfil\displaystyle{#1}\hfil$\crcr}}} + +\def\skew#1#2#3% + {{\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[]} +\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% can be mkiv'd + {\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\zerocount#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-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-pln.tex b/tex/context/base/math-pln.tex deleted file mode 100644 index ffa16c8f5..000000000 --- a/tex/context/base/math-pln.tex +++ /dev/null @@ -1,355 +0,0 @@ -%D \module -%D [ file=math-pln, -%D version=2001.11.16, -%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 is a temporary module, some of this code will move to -%D the other math modules. - -\unprotect - -\ifx\displ@y\unefined \let\displ@y\relax\fi -\ifx\m@th \unefined \let\m@th \relax\fi - -\newbox\rootbox - -\def\root#1\of% - {\setbox\rootbox\hbox{$\m@th\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@ - \mkern5mu\raise.6\dimen@\copy\rootbox - \mkern-10mu\box\z@} - -\def\mathhexbox#1#2#3% - {\leavevmode - \hbox{$\m@th\mathchar"#1#2#3$}} - -\def\oalign#1% - {\leavevmode - \vtop - {\baselineskip\z@skip \lineskip.25ex% - \ialign{##\crcr#1\crcr}}} - -\def\o@lign - {\lineskiplimit\z@ \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$\m@th\ldots\,$\fi} - -\def\hrulefill - {\leaders\hrule\hfill} - -\def\dotfill - {\cleaders\hbox{$\m@th \mkern1.5mu.\mkern1.5mu$}\hfill} - -\def\rightarrowfill - {$\m@th\smash-\mkern-7mu% - \cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill - \mkern-7mu\mathord\rightarrow$} - -\def\leftarrowfill - {$\m@th\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 - -\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$} - -\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$} - -\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\overrightarrow#1% - {\vbox{\m@th\ialign{##\crcr - \rightarrowfill\crcr\noalign{\kern-\p@\nointerlineskip} - $\hfil\displaystyle{#1}\hfil$\crcr}}} - -\def\overleftarrow#1% - {\vbox{\m@th\ialign{##\crcr - \leftarrowfill\crcr\noalign{\kern-\p@\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} - -\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\p@\vbox{\lineskiplimit\maxdimen\lineskip-.5\p@ - \ialign{$\m@th#1\hfil##\hfil$\crcr#2\crcr=\crcr}}} - -\def\notin% - {\mathrel{\mathpalette\c@ncel\in}} - -\def\c@ncel#1#2% - {\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}} - -\def\rightleftharpoons% - {\mathrel{\mathpalette\rlh@{}}} - -\def\rlh@#1% - {\vcenter - {\m@th - \hbox - {\ooalign - {\raise2pt\hbox{$#1\rightharpoonup$}\crcr - $#1\leftharpoondown$}}}} - -\def\buildrel#1\over#2% - {\mathrel{\mathop{\kern\z@#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 - \m@th - \ialign{$##\hfil$&\quad##\hfil\crcr#1\crcr}}% - \right.} - -\def\matrix#1% - {\null - \,% - \vcenter - {\normalbaselines\m@th - \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\p@renwd - -% \setbox0=\hbox{\tenex B} \p@renwd=\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 - &&\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)$}% - \null - \;% - \vbox{\kern\ht\@ne\box\tw@}% - \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 - \m@th - \ialign - {\strut\hfil$\displaystyle{##}$&$\displaystyle{{}##}$\hfil\crcr - #1\crcr}}% - \,} - -\def\@lign % restore inside \displ@y - {\tabskip\z@skip - \everycr{}} - -\def\displaylines#1% - {\displ@y - \tabskip\z@skip - \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\z@skip - &$\@lign\displaystyle{{}##}$\hfil\tabskip\centering - &\llap{$\@lign##$}\tabskip\z@skip\crcr - #1\crcr}} - -\def\leqalignno#1% - {\displ@y - \tabskip\centering - \halign to \displaywidth - {\hfil$\@lign\displaystyle{##}$\tabskip\z@skip - &$\@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.mkii b/tex/context/base/math-run.mkii new file mode 100644 index 000000000..afe5b18b4 --- /dev/null +++ b/tex/context/base/math-run.mkii @@ -0,0 +1,97 @@ +%D \module +%D [ file=math-run, +%D version=2001.23.04, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Runtime Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=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 Math Macros / Runtime Macros} + +\unprotect + +\ifx\showmathmodern\undefined \global\chardef\showmathmodern\zerocount \fi + +\gdef\showmathcharacters% nearly \showcharacters + {\par + \bgroup + \ifcase\showmathmodern\or\ifx\modern\undefined\chardef\showmathmodern\zerocount\fi\fi + \setuptextrules[\c!bodyfont=,\c!style=] + \starttextrule{math characters -- \currentmathcollection} + \whitespace + \dontcomplain + \forgetall + \def\startmathcollection[##1]{} + \let\stopmathcollection\relax + \dimen0\zeropoint + \dimen2\zeropoint + \def\definemathsymbol {\dosixtupleempty\dodefinemathsymbol} + \def\definemathcharacter{\dosixtupleempty\dodefinemathcharacter} + \def\definemathcommand {\dotripleempty \dodefinemathcommand} + %\newcounter\mathcolor + \def\dodefinemathsymbol[##1][##2][##3][##4][##5][##6]% + {%\doifcolorelse{math \purefamilyhex{##3}}{} + % {\increment\mathcolor + % \definecolor[math \purefamilyhex{##3}][\mathcolor]}% + \setbox0\hbox spread 1em{\mathematics{\getvalue{##1}{}{}{}}}% + \ifdim\wd0>\dimen0 \dimen0=\wd0 \fi + \setbox2\hbox spread 1em{\hbox to 1em{\tttf\purefamilyhex{##3}\hss}\box0 ##1}% + \ifdim\wd2>\dimen2 \dimen2=\wd2 \fi} + \def\dodefinemathcharacter[##1][##2][##3][##4][##5][##6]{} + \def\dodefinemathcommand [##1][##2][##3]##4{} + \readsysfile{\f!mathprefix tex}\donothing\donothing + \readsysfile{\f!mathprefix ams}\donothing\donothing + \edef\encwidth{\the\dimen0} + \dimen0=\hsize + \advance\dimen0 2em + \advance\dimen2 2em + \ifcase\showmathmodern\or\advance\dimen2 4em\fi + \divide \dimen0 by \dimen2 \advance\dimen0 1sp + \edef\enccols{\number\dimen0} + \startcolumns[\c!n=\enccols,\c!distance=2em] + \def\dodefinemathsymbol[##1][##2][##3][##4][##5][##6]% + {%\localcolortrue + %\color + % [math \purefamilyhex{##3}] + {\hbox + {\ifcase\showmathmodern\or + \hbox to \encwidth{\modern\let\mathcollection\nomathcollection\mathematics{\getvalue{##1}{}{}{}}\hss}% + \fi + \hbox to \encwidth{\mathematics{\getvalue{##1}{}{}{}}\hss}% + \hbox to 1em{\tttf\purefamilyhex{##3}\hss}##1}\par}} + \readsysfile{\f!mathprefix tex}\donothing\donothing + \readsysfile{\f!mathprefix ams}\donothing\donothing + \stopcolumns + \stoptextrule + \egroup} + +% \definecolor[math \purefamilyhex{mr}] [darkred] +% \definecolor[math \purefamilyhex{mi}] [darkgreen] +% \definecolor[math \purefamilyhex{sy}] [darkblue] +% \definecolor[math \purefamilyhex{ex}] [darkmagenta] +% \definecolor[math \purefamilyhex{nn}] [darkyellow] +% \definecolor[math \purefamilyhex{ma}] [lightred] +% \definecolor[math \purefamilyhex{mb}] [lightgreen] +% \definecolor[math \purefamilyhex{mc}] [lightblue] +% \definecolor[math \purefamilyhex{md}] [lightmagenta] + +\gdef\showmathtoken#1% + {\starttabulate[|lT|lT|lT|l|] + \NC token \NC #1 \NC \NR + \NC collection \NC \ifcsname\@mt@\mathcollection#1\endcsname + \mathcollection + \else\ifcsname\@mt@\nomathcollection#1\endcsname + \nomathcollection + \else + ?% + \fi\fi \NC \NR + \NC visualization \NC \mathematics{\getvalue{#1}} \NC \NR + \NC definition \NC \tttf \@EA\defconvertedcommand\@EA\ascii\csname\@mt@\mathcollection#1\endcsname \ascii \NC \NR + \stoptabulate} + +\protect \endinput diff --git a/tex/context/base/math-run.tex b/tex/context/base/math-run.tex deleted file mode 100644 index affa8d5af..000000000 --- a/tex/context/base/math-run.tex +++ /dev/null @@ -1,95 +0,0 @@ -%D \module -%D [ file=math-run, -%D version=2001.23.04, -%D title=\CONTEXT\ Math Macros, -%D subtitle=Runtime Macros, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=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 - -\ifx\showmathmodern\undefined \global\chardef\showmathmodern\zerocount \fi - -\gdef\showmathcharacters% nearly \showcharacters - {\par - \bgroup - \ifcase\showmathmodern\or\ifx\modern\undefined\chardef\showmathmodern\zerocount\fi\fi - \setuptextrules[\c!bodyfont=,\c!style=] - \starttextrule{math characters -- \currentmathcollection} - \whitespace - \dontcomplain - \forgetall - \def\startmathcollection[##1]{} - \let\stopmathcollection\relax - \dimen0\zeropoint - \dimen2\zeropoint - \def\definemathsymbol {\dosixtupleempty\dodefinemathsymbol} - \def\definemathcharacter{\dosixtupleempty\dodefinemathcharacter} - \def\definemathcommand {\dotripleempty \dodefinemathcommand} - %\newcounter\mathcolor - \def\dodefinemathsymbol[##1][##2][##3][##4][##5][##6]% - {%\doifcolorelse{math \purefamilyhex{##3}}{} - % {\increment\mathcolor - % \definecolor[math \purefamilyhex{##3}][\mathcolor]}% - \setbox0\hbox spread 1em{\mathematics{\getvalue{##1}{}{}{}}}% - \ifdim\wd0>\dimen0 \dimen0=\wd0 \fi - \setbox2\hbox spread 1em{\hbox to 1em{\tttf\purefamilyhex{##3}\hss}\box0 ##1}% - \ifdim\wd2>\dimen2 \dimen2=\wd2 \fi} - \def\dodefinemathcharacter[##1][##2][##3][##4][##5][##6]{} - \def\dodefinemathcommand [##1][##2][##3]##4{} - \readsysfile{\f!mathprefix tex}\donothing\donothing - \readsysfile{\f!mathprefix ams}\donothing\donothing - \edef\encwidth{\the\dimen0} - \dimen0=\hsize - \advance\dimen0 2em - \advance\dimen2 2em - \ifcase\showmathmodern\or\advance\dimen2 4em\fi - \divide \dimen0 by \dimen2 \advance\dimen0 1sp - \edef\enccols{\number\dimen0} - \startcolumns[\c!n=\enccols,\c!distance=2em] - \def\dodefinemathsymbol[##1][##2][##3][##4][##5][##6]% - {%\localcolortrue - %\color - % [math \purefamilyhex{##3}] - {\hbox - {\ifcase\showmathmodern\or - \hbox to \encwidth{\modern\let\mathcollection\nomathcollection\mathematics{\getvalue{##1}{}{}{}}\hss}% - \fi - \hbox to \encwidth{\mathematics{\getvalue{##1}{}{}{}}\hss}% - \hbox to 1em{\tttf\purefamilyhex{##3}\hss}##1}\par}} - \readsysfile{\f!mathprefix tex}\donothing\donothing - \readsysfile{\f!mathprefix ams}\donothing\donothing - \stopcolumns - \stoptextrule - \egroup} - -% \definecolor[math \purefamilyhex{mr}] [darkred] -% \definecolor[math \purefamilyhex{mi}] [darkgreen] -% \definecolor[math \purefamilyhex{sy}] [darkblue] -% \definecolor[math \purefamilyhex{ex}] [darkmagenta] -% \definecolor[math \purefamilyhex{nn}] [darkyellow] -% \definecolor[math \purefamilyhex{ma}] [lightred] -% \definecolor[math \purefamilyhex{mb}] [lightgreen] -% \definecolor[math \purefamilyhex{mc}] [lightblue] -% \definecolor[math \purefamilyhex{md}] [lightmagenta] - -\gdef\showmathtoken#1% - {\starttabulate[|lT|lT|lT|l|] - \NC token \NC #1 \NC \NR - \NC collection \NC \ifcsname\@mt@\mathcollection#1\endcsname - \mathcollection - \else\ifcsname\@mt@\nomathcollection#1\endcsname - \nomathcollection - \else - ?% - \fi\fi \NC \NR - \NC visualization \NC \mathematics{\getvalue{#1}} \NC \NR - \NC definition \NC \tttf \@EA\defconvertedcommand\@EA\ascii\csname\@mt@\mathcollection#1\endcsname \ascii \NC \NR - \stoptabulate} - -\protect \endinput 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 {file} +%D \pdfimages {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 {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 +%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 : 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 + {<>}% + \immediate\pdfobj + {<>}% + \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 +%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 : 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 + {<>}% + \immediate\pdfobj + {<>}% + \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 {file} -%D \pdfimages {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 {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 -%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 : 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 - {<>}% - \immediate\pdfobj - {<>}% - \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 + +% 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{<>}% \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{<>}% -% \immediate\pdfobj{<>}% -% \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{<>}% \immediate\pdfobj{<>}% @@ -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'] = {

The directional helpers and pen analysis are more or less translated from the code. It really helps that Taco know that source so well. Taco and I spent quite some time on speeding up the and code. There is not -much to gain, especially if on ekeeps in mind that when integrated in +much to gain, especially if one keeps in mind that when integrated in only a part of the time is spent in . Of course an integrated approach is way faster than an external and processing time nears zero.

@@ -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-- +

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.

+--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-- -

Access to nodes is what gives its power. Here we -implement a few helper functions. These functions are rather optimized.

+

Most of the code that had accumulated here is now separated in +modules.

--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-- +

We start with a registration system for atributes so that we can use the +symbolic names later on.

+--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-- +

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 .

+--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-- +

Access to nodes is what gives its power. Here we +implement a few helper functions. These functions are rather optimized.

+--ldx]]-- --[[ldx--

When manipulating node lists in , we will remove @@ -255,963 +98,136 @@ into the engine, but this is a not so natural extension.

also ignore the empty nodes. [This is obsolete!]

--ldx]]-- +nodes = nodes or { } ---[[ldx-- -

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.

---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-- +

The next function is not that much needed but in we use +for debugging node management.

+--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-- +

Here we implement a mechanism for chaining the special functions +that we use in 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.

+--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-- +

This is rather experimental. We need more control and some of this +might become a runtime module instead.

+--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 "" + 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/norm-xtx.tex b/tex/context/base/norm-xtx.tex new file mode 100644 index 000000000..3da944656 --- /dev/null +++ b/tex/context/base/norm-xtx.tex @@ -0,0 +1,18 @@ +%D \module +%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] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% 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.mkii b/tex/context/base/page-bck.mkii new file mode 100644 index 000000000..0b4ad779a --- /dev/null +++ b/tex/context/base/page-bck.mkii @@ -0,0 +1,593 @@ +%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 + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +% messages moved + +%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 +%D \addtextbackground +%D \addpagebackground +%D \addprintbackground +%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.) + +\def\checkbackground#1% + {\edef\!!stringe{\??ma#1}% + \doifelsevaluenothing{\!!stringe\c!background } + {\doifelsevaluenothing{\!!stringe\c!foregroundcolor} + {\doifelsevalue{\!!stringe\c!frame }\v!on\!!doneatrue + {\doifelsevalue{\!!stringe\c!leftframe }\v!on\!!doneatrue + {\doifelsevalue{\!!stringe\c!rightframe}\v!on\!!doneatrue + {\doifelsevalue{\!!stringe\c!topframe }\v!on\!!doneatrue + {\doifelsevalue{\!!stringe\c!bottomframe }\v!on\!!doneatrue + \!!doneafalse}}}}} + \!!doneatrue} + \!!doneatrue + \if!!donea + \setusage \!!stringe + \else + \resetusage\!!stringe + \fi} + +\def\ifsomebackgroundfound#1% + {\ifusage{\??ma#1}} + +% \def\doifsomebackgroundelse#1#2#3% +% {\ifusage{\??ma#1}#2\else#3\fi} + +\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 + \doifvaluesomething{\??ma#1\c!setups}{\setups[\getvalue{\??ma#1\c!setups}]}% should not produce funny spaces ! + \setbox#2\vbox\fastlocalframed + [\??ma#1] + [\c!component=#1,\c!strut=\v!no,\c!offset=\v!overlay,\c!setups=,% + \c!width=#3,\c!height=#4] + {\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 + \doifvaluesomething{\??ma#3#4\c!setups}{\setups[\getvalue{\??ma#3#4\c!setups}]}% should not produce funny spaces ! + \fastlocalframed + [\??ma#3#4] + [\c!component=#3-#4,\c!offset=\v!overlay,\c!setups=] + {\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. + +\presetlocalframed [\??ma\v!paper] +\presetlocalframed [\??ma\v!page] +\presetlocalframed [\??ma\v!leftpage] +\presetlocalframed [\??ma\v!rightpage] + +\copyparameters + [\??ma\v!paper\c!frame][\??ma\v!page] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!paper\c!background][\??ma\v!page] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!page\c!frame][\??ma\v!page] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!page\c!background][\??ma\v!page] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!leftpage\c!frame][\??ma\v!leftpage] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!leftpage\c!background][\??ma\v!leftpage] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!rightpage\c!frame][\??ma\v!rightpage] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +\copyparameters + [\??ma\v!rightpage\c!background][\??ma\v!rightpage] + [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] + +%D We save some keying by defining the areas using +%D intermediate commands. The inheritance macro makes sure +%D that copies are efficient. + +\def\dodocommand#1#2% + {\copylocalframed + [\??ma#1#2][\??ma\v!page]% + \getparameters + [\??ma#1#2] + [\c!background=,\c!frame=,\c!color=,\c!screen=\@@rsscreen, + \c!bottomframe=,\c!topframe=,\c!leftframe=,\c!rightframe=]% + \inheritparameter[\??ma][#1#2\c!color][\v!page\c!color]% + \inheritparameter[\??ma][#1#2\c!screen][\v!page\c!screen]% + \inheritparameter[\??ma][#1#2\c!framecolor][\v!page\c!framecolor]% + \inheritparameter[\??ma][#1#2\c!backgroundcolor][\v!page\c!backgroundcolor]% + \inheritparameter[\??ma][#1#2\c!backgroundscreen][\v!page\c!backgroundscreen]} + +%D The stand alone text area inherits from the page too. + +\dodocommand\v!text \empty +\dodocommand\v!hidden\empty + +%D We now define all 25 main areas in a row. + +\def\docommand#1% + {\dodocommand#1\v!leftedge + \dodocommand#1\v!leftmargin + \dodocommand#1\v!text + \dodocommand#1\v!rightmargin + \dodocommand#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\dodocommand\relax \let\docommand\relax + +%D We now set up the individual areas to use reasonable +%D defaults. + +\setupbackgrounds + [\c!state=\c!start] + +\setupbackgrounds + [\v!paper,\v!page,\v!leftpage,\v!rightpage] + [\c!frame=\v!off, + \c!radius=.5\bodyfontsize, + \c!corner=\v!rectangular, + \c!background=, + \c!screen=\@@rsscreen, + \c!color=, + %\c!frameoffset=\getvalue{\??ma\v!page\c!offset}, + %\c!backgroundoffset=\getvalue{\??ma\v!page\c!offset}, + \c!offset=\!!zeropoint, % later set to \v!overlay, watch out ! + \c!depth=\!!zeropoint] + +\def\docommand#1% + {\inheritparameter[\??ma][#1\c!frameoffset][\v!page\c!offset]% + \inheritparameter[\??ma][#1\c!backgroundoffset][\v!page\c!offset]} + +\docommand\v!paper +\docommand\v!page +\docommand\v!leftpage +\docommand\v!rightpage + +%D Again we clean up temporary macros. + +\let\docommand\relax + +%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. + +\presetlocalframed + [\??ma\v!local] + +\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 % \localframed + [\??ma\v!local] + [\c!component=local,\c!frame=\v!off,\c!offset=\v!overlay,\c!setups=,% + \c!location=\v!keep,% when we use \localframed instead of \fastlocalframed + \c!background=\localbackground]% + {\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-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 +%D \addtextbackground +%D \addpagebackground +%D \addprintbackground +%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-bck.tex b/tex/context/base/page-bck.tex deleted file mode 100644 index 10123fec6..000000000 --- a/tex/context/base/page-bck.tex +++ /dev/null @@ -1,615 +0,0 @@ -%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 - -\startmessages dutch library: layouts - 8: achtergronden berekenen -\stopmessages - -\startmessages english library: layouts - 8: calculating backgrounds -\stopmessages - -\startmessages german library: layouts - 8: berechne Hintergrund -\stopmessages - -\startmessages czech library: layouts - 8: pocita se pozadi -\stopmessages - -\startmessages italian library: layouts - 8: calcolo dello sfondo -\stopmessages - -\startmessages norwegian library: layouts - 8: beregner bakgrunn -\stopmessages - -\startmessages romanian library: layouts - 8: se calculeaza fundalurile -\stopmessages - -\startmessages french library: layouts - 8: calcul des arrières-plans -\stopmessages - -%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 -%D \addtextbackground -%D \addpagebackground -%D \addprintbackground -%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.) - -\def\checkbackground#1% - {\edef\!!stringe{\??ma#1}% - \doifelsevaluenothing{\!!stringe\c!background } - {\doifelsevaluenothing{\!!stringe\c!foregroundcolor} - {\doifelsevalue{\!!stringe\c!frame }\v!on\!!doneatrue - {\doifelsevalue{\!!stringe\c!leftframe }\v!on\!!doneatrue - {\doifelsevalue{\!!stringe\c!rightframe}\v!on\!!doneatrue - {\doifelsevalue{\!!stringe\c!topframe }\v!on\!!doneatrue - {\doifelsevalue{\!!stringe\c!bottomframe }\v!on\!!doneatrue - \!!doneafalse}}}}} - \!!doneatrue} - \!!doneatrue - \if!!donea - \setusage \!!stringe - \else - \resetusage\!!stringe - \fi} - -\def\ifsomebackgroundfound#1% - {\ifusage{\??ma#1}} - -% \def\doifsomebackgroundelse#1#2#3% -% {\ifusage{\??ma#1}#2\else#3\fi} - -\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 - \doifvaluesomething{\??ma#1\c!setups}{\setups[\getvalue{\??ma#1\c!setups}]}% should not produce funny spaces ! - \setbox#2\vbox\fastlocalframed - [\??ma#1] - [\c!component=#1,\c!strut=\v!no,\c!offset=\v!overlay,\c!setups=,% - \c!width=#3,\c!height=#4] - {\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 - \doifvaluesomething{\??ma#3#4\c!setups}{\setups[\getvalue{\??ma#3#4\c!setups}]}% should not produce funny spaces ! - \fastlocalframed - [\??ma#3#4] - [\c!component=#3-#4,\c!offset=\v!overlay,\c!setups=] - {\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!linkertekst,\v!rechtertekst,% - \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 - -\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. - -\presetlocalframed [\??ma\v!paper] -\presetlocalframed [\??ma\v!page] -\presetlocalframed [\??ma\v!leftpage] -\presetlocalframed [\??ma\v!rightpage] - -\copyparameters - [\??ma\v!paper\c!frame][\??ma\v!page] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!paper\c!background][\??ma\v!page] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!page\c!frame][\??ma\v!page] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!page\c!background][\??ma\v!page] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!leftpage\c!frame][\??ma\v!leftpage] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!leftpage\c!background][\??ma\v!leftpage] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!rightpage\c!frame][\??ma\v!rightpage] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -\copyparameters - [\??ma\v!rightpage\c!background][\??ma\v!rightpage] - [\c!offset,\c!depth,\c!radius,\c!corner,\c!color,\c!screen] - -%D We save some keying by defining the areas using -%D intermediate commands. The inheritance macro makes sure -%D that copies are efficient. - -\def\dodocommand#1#2% - {\copylocalframed - [\??ma#1#2][\??ma\v!page]% - \getparameters - [\??ma#1#2] - [\c!background=,\c!frame=,\c!color=,\c!screen=\@@rsscreen, - \c!bottomframe=,\c!topframe=,\c!leftframe=,\c!rightframe=]% - \inheritparameter[\??ma][#1#2\c!color][\v!page\c!color]% - \inheritparameter[\??ma][#1#2\c!screen][\v!page\c!screen]% - \inheritparameter[\??ma][#1#2\c!framecolor][\v!page\c!framecolor]% - \inheritparameter[\??ma][#1#2\c!backgroundcolor][\v!page\c!backgroundcolor]% - \inheritparameter[\??ma][#1#2\c!backgroundscreen][\v!page\c!backgroundscreen]} - -%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 - -%D We now define all 25 main areas in a row. - -\def\docommand#1% - {\dodocommand#1\v!leftedge - \dodocommand#1\v!leftmargin - \dodocommand#1\v!text - \dodocommand#1\v!rightmargin - \dodocommand#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\dodocommand\relax \let\docommand\relax - -%D We now set up the individual areas to use reasonable -%D defaults. - -\setupbackgrounds - [\c!state=\c!start] - -\setupbackgrounds - [\v!paper,\v!page,\v!leftpage,\v!rightpage] - [\c!frame=\v!off, - \c!radius=.5\bodyfontsize, - \c!corner=\v!rectangular, - \c!background=, - \c!screen=\@@rsscreen, - \c!color=, - %\c!frameoffset=\getvalue{\??ma\v!page\c!offset}, - %\c!backgroundoffset=\getvalue{\??ma\v!page\c!offset}, - \c!offset=\!!zeropoint, % later set to \v!overlay, watch out ! - \c!depth=\!!zeropoint] - -\def\docommand#1% - {\inheritparameter[\??ma][#1\c!frameoffset][\v!page\c!offset]% - \inheritparameter[\??ma][#1\c!backgroundoffset][\v!page\c!offset]} - -\docommand\v!paper -\docommand\v!page -\docommand\v!leftpage -\docommand\v!rightpage - -%D Again we clean up temporary macros. - -\let\docommand\relax - -%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. - -\presetlocalframed - [\??ma\v!local] - -\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 % \localframed - [\??ma\v!local] - [\c!component=local,\c!frame=\v!off,\c!offset=\v!overlay,\c!setups=,% - \c!location=\v!keep,% when we use \localframed instead of \fastlocalframed - \c!background=\localbackground]% - {\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{} - {\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.mkii b/tex/context/base/page-ini.mkii new file mode 100644 index 000000000..e5c3aa41a --- /dev/null +++ b/tex/context/base/page-ini.mkii @@ -0,0 +1,1555 @@ +%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 % + +\fi + +\ifx\recalculatebackgrounds\undefined + + \let \recalculatebackgrounds \relax + \let \addmainbackground \gobbleoneargument % + \let \addtextbackground \gobbleoneargument % + \let \addpagebackground \gobbleoneargument % + \let \addprintbackground \gobbleoneargument % + \let \addstatusinfo \gobbleoneargument % + +\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 + \ifspecialbasedsettings + \myshipout{\hbox{\hbox to \zeropoint{\the\pageboundsettings}% + \hbox{\vbox{\dopagebody#1#2\setpagecounters}}}}% + \else + \the\pageboundsettings + \myshipout{\hbox{\vbox{\dopagebody#1#2\setpagecounters}}}% + \fi + \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 + \checkreferences + \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-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 % + +\fi + +\ifx\recalculatebackgrounds\undefined + + \let \recalculatebackgrounds \relax + \let \addmainbackground \gobbleoneargument % + \let \addtextbackground \gobbleoneargument % + \let \addpagebackground \gobbleoneargument % + \let \addprintbackground \gobbleoneargument % + \let \addstatusinfo \gobbleoneargument % + +\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-ini.tex b/tex/context/base/page-ini.tex deleted file mode 100644 index 61cd91b2b..000000000 --- a/tex/context/base/page-ini.tex +++ /dev/null @@ -1,2034 +0,0 @@ -%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 - -% 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} - -\chardef\normalpagebox=255 - -\newbox\pagebox - -\ifx\recalculatelayout\undefined - - \let \recalculatelayout \relax - -\fi - -\ifx\recalculatelogos\undefined - - \let \recalculatelogos \relax - \let \addlogobackground \gobbleoneargument % - -\fi - -\ifx\recalculatebackgrounds\undefined - - \let \recalculatebackgrounds \relax - \let \addmainbackground \gobbleoneargument % - \let \addtextbackground \gobbleoneargument % - \let \addpagebackground \gobbleoneargument % - \let \addprintbackground \gobbleoneargument % - \let \addstatusinfo \gobbleoneargument % - -\fi - -\ifx\realpageno\undefined - - \countdef\realpageno\zerocount \realpageno\plusone - -\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 - -\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 - -\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{-\@M} \let\ejectpenalty\normalejectpenalty -\def\normalsuperpenalty{-\@MM} \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-\@M'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-\@M } % == {\par\break} % plain -% \def\supereject {\par\penalty-\@MM} % 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 - \ifspecialbasedsettings - \myshipout{\hbox{\hbox to \zeropoint{\the\pageboundsettings}% - \hbox{\vbox{\dopagebody#1#2\setpagecounters}}}}% - \else - \the\pageboundsettings - \myshipout{\hbox{\vbox{\dopagebody#1#2\setpagecounters}}}% - \fi - \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 - \checkreferences - \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\ifpaginageblokkeerd \paginageblokkeerdfalse - -% \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 -% \ifpaginageblokkeerd -% % 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 - \ifpaginageblokkeerd - \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\paginageblokkeerdfalse} - -\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\paginageblokkeerdtrue} - -\installpagebreakhandler \v!yes - {\ifpaginageblokkeerd\else - \ejectinsert - \gotonextpage - \ifinsidecolumns % this will move to MUL - \ejectpage % anders soms geen overgang - \fi - \fi} - -\installpagebreakhandler \v!makeup % ?? - {\ifpaginageblokkeerd\else - \eject - \fi} - -\installpagebreakhandler \v!blank - {\ifcase\pageornamentstate - \global\chardef\pageornamentstate\plusone - \fi} - -\installpagebreakhandler \v!no - {\ifpaginageblokkeerd\else - \dosomebreak\nobreak - \fi} - -\installpagebreakhandler \v!preference - {\ifpaginageblokkeerd\else - \ifinsidecolumns % this will move to MUL - \dosomebreak\goodbreak - \else - \testpage[3][\zeropoint]% - \fi - \fi} - -\installpagebreakhandler \v!bigpreference - {\ifpaginageblokkeerd\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): - -\ifx\undefined\normalshipout \let\normalshipout=\shipout \fi - -\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.mkii b/tex/context/base/page-one.mkii new file mode 100644 index 000000000..1affc24d0 --- /dev/null +++ b/tex/context/base/page-one.mkii @@ -0,0 +1,659 @@ +%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 \unvbox + {\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 + \snaptogrid\hbox{\box\botins}% + \else + \unvbox\botins + \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 + \dochecknextindentation\??bk + \dorechecknextindentation} + +% \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-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 \unvbox + {\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-one.tex b/tex/context/base/page-one.tex deleted file mode 100644 index f33aa4602..000000000 --- a/tex/context/base/page-one.tex +++ /dev/null @@ -1,659 +0,0 @@ -%D \module -%D [ file=page-one, -%D version=2000.10.20, -%D title=\CONTEXT\ OTR 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 OTR 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 \unvbox - {\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 - \snaptogrid\hbox{\box\botins}% - \else - \unvbox\botins - \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 - \dochecknextindentation\??bk - \dorechecknextindentation} - -% \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.mkii b/tex/context/base/page-txt.mkii new file mode 100644 index 000000000..9fe73bec1 --- /dev/null +++ b/tex/context/base/page-txt.mkii @@ -0,0 +1,784 @@ +%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. + +% \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 <\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} + \@@plaatspaginanummer + {\ConvertConstantAfter\doifelse\v!date{#6} + {\currentdate} + {% #6{}{}{} -> {} needed for macros that look + % ahead, like \uniqueMPgraphic + \opeenregel\dolimitatetexts{#1#2#5}{#6{}{}{}}}}}}}% + \egroup} + +%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 + \ifundefined{\string\placelayouttextline\textlinestatus}% + \s!unknown + \else + \textlinestatus + \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/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 <\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/page-txt.tex b/tex/context/base/page-txt.tex deleted file mode 100644 index b40ecb16e..000000000 --- a/tex/context/base/page-txt.tex +++ /dev/null @@ -1,784 +0,0 @@ -%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. - -% \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 <\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} - \@@plaatspaginanummer - {\ConvertConstantAfter\doifelse\v!date{#6} - {\currentdate} - {% #6{}{}{} -> {} needed for macros that look - % ahead, like \uniqueMPgraphic - \opeenregel\dolimitatetexts{#1#2#5}{#6{}{}{}}}}}}}% - \egroup} - -%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 - \ifundefined{\string\placelayouttextline\textlinestatus}% - \s!unknown - \else - \textlinestatus - \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 - \box\scratchpagebox - \localstoptextcolor - \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.mkii b/tex/context/base/ppchtex.mkii new file mode 100644 index 000000000..285b0004e --- /dev/null +++ b/tex/context/base/ppchtex.mkii @@ -0,0 +1,3457 @@ +%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 + +% De onderstaande help-informatie (%I) kan worden opgeroepen +% in TeXEdit. De daaropvolgende setup-informatie (%S) kan +% nadat zij is uit deze file is gefilterd met TeXUtil, in +% handleidingen worden gebruikt. In deze file opgenomen +% documentatie (%D en %M) kan worden gebruikt voor een +% technische handleiding. Met %T kunnen templates worden +% gedefinieerd voor TeXEdit. + +%I n=Chemie +%I c=\stelchemiein,\chemie +%I +%I Chemische formules kunnen worden gezet met behulp van de +%I onderstaande commando's: +%I +%I buiten $ en $$ : +%I +%I \chemie[segmenten][symbolen] +%I +%I \startchemie[instellingen] +%I \chemie... +%I \chemie... +%I \stopchemie +%I +%I en binnen $ en $$: +%I +%I \chemie{}{} +%I +%I Voor tekst, uitleg en voorbeelde verwijzen we vooralsnog +%I naar de handleiding. +%P +%I Het gedrag van de macro's kan worden ingesteld met: +%I +%I \stelchemiein[breedte=,hoogte=,links=,rechts=,boven=, +%I onder=,korps=,schaal=,status=,assenstelsel=,kader=, +%I variant=,optie=,formaat=,tekstformaat=,resolutie=, +%I offset=,letter=] +%I +%I Structuren kunnen worden voorgedefinieerd met het commando +%I +%I \definieerchemie[naam]{\chemie...} + +%S \startsetup +%S \command +%S [\!stelchemiein] +%S \type +%S [\c!vars!] +%S \variable +%S [\c!breedte] +%S [\c!number!,\v!passend] +%S [0] +%S \variable +%S [\c!hoogte] +%S [\c!number!,\v!passend] +%S [0] +%S \variable +%S [\c!links] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!rechts] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!boven] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!onder] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!resolutie] +%S [\c!number!] +%S [\outputresolution] +%S \variable +%S [\c!korps] +%S [10pt,11pt,12pt] +%S [\bodyfontsize] +%S \variable +%S [\c!schaal] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!middel] +%S \variable +%S [\c!formaat] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!groot] +%S \variable +%S [\c!tekstformaat] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!groot] +%S \variable +%S [\c!status] +%S [\v!start,\v!stop] +%S [\v!start] +%S \variable +%S [\c!kader] +%S [\v!aan,\v!uit] +%S [\v!uit] +%S \variable +%S [\c!assenstelsel] +%S [\v!aan,\v!uit] +%S [\v!uit] +%S \variable +%S [\c!optie] +%S [\v!test] +%S [] +%S \variable +%S [\c!variant] +%S [1,2] +%S [1] +%S \variable +%S [\c!offset] +%S [HIGH,LOW] +%S [LOW] +%S \variable +%S [\c!letter] +%S [\c!command!] +%S [\rm] +%S \stopsetup + +%S \startsetup +%S \command +%S [\v!startchemie] +%S \type +%S [\c!vars!\c!stp!] +%S \inheritvariable +%S [\v!stelchemiein] +%S [] +%S \stopsetup + +%S \startsetup +%S \command +%S [\v!chemie] +%S \type +%S [\c!vals!\c!vals!] +%S \value +%S [\c!list!] +%S [] +%S \value +%S [\c!list!] +%S [] +%S \stopsetup + +%S \startsetup +%S \command +%S [definieerchemie] +%S \type +%S [\c!val!\c!arg!] +%S \value +%S [\c!text!] +%S [] +%S \stopsetup + +\unprotect + +% Om te voorkomen dat sub- en superscripts botsen passen we +% wat fontdimen's aan (Knuth, The TeXBook, p179). Helaas +% kunnen deze instellingen niet lokaal worden gehouden door +% groeperen, vandaar dat een en ander moet worden geset n +% gereset. +% +% Er dient een relatie te worden gelegd met de afmetingen +% van de letters. In een eerdere versie werden daartoe de +% \fontdimen's opgehoogd. Omdat dit problemen gaf bij +% scaled fonts, is bij nader inzien gekozen voor de +% onderstaande oplossing, waarbij de nieuwe waarden worden +% afgeleid van de x-height (\fontexheight). De factor 0.70 +% is min of meer experimenteel vastgesteld. Soms worden de +% regels iets verder uit elkaar gezet. Jammer. Italic fonts +% hebben grotere cijfers en vallen min of meer uit de boot. + +\newif\ifloweredsubscripts + +% Due to some upward incompatibality of LaTeX to LaTeX2.09 +% and/or LaTeX2e we had to force \@@dochemicalstyle. Otherwise +% some weird \nullfont error comes up. + +\def\beginlatexmathmodehack + {\ifmmode + \let\endlatexmathmodehack=\relax + \else + \def\endlatexmathmodehack{$}$\@@dochemicalstyle\empty + \fi} + +\def\setsubscripts% + {\beginlatexmathmodehack + \def\dosetsubscript##1##2##3% + {\dimen0=##3\fontexheight##2% + \setxvalue{@@\string##1\string##2}{\the##1##2\relax}% + ##1##2=\dimen0\relax}% + \def\dodosetsubscript##1##2% + {\dosetsubscript{##1}{\textfont 2}{##2}% + \dosetsubscript{##1}{\scriptfont 2}{##2}% + \dosetsubscript{##1}{\scriptscriptfont2}{##2}}% + %dodosetsubscript\mathsupnormal {?}% + \dodosetsubscript\mathsubnormal {.7}% + \dodosetsubscript\mathsubcombined{.7}% + \global\loweredsubscriptstrue + \endlatexmathmodehack} + +\def\resetsubscripts + {\ifloweredsubscripts + \beginlatexmathmodehack + \def\doresetsubscript##1##2% + {\dimen0=\getvalue{@@\string##1\string##2}\relax + ##1##2=\dimen0}% + \def\dodoresetsubscript##1% + {\doresetsubscript{##1}{\textfont2}% + \doresetsubscript{##1}{\scriptfont2}% + \doresetsubscript{##1}{\scriptscriptfont2}}% + %dodoresetsubscript\mathsupnormal + \dodoresetsubscript\mathsubnormal + \dodoresetsubscript\mathsubcombined + \global\loweredsubscriptsfalse + \endlatexmathmodehack + \fi} + +\ifx\Umathchar\undefined \else + % for the moment we nil them, soon we will have a proper + % way to deal with this + \let\setsubscripts \relax + \let\resetsubscripts\relax +\fi + +\def\doresetsubscripts + {\resetsubscripts} + +\def\sethighsubscripts + {\resetsubscripts + \let\dosetsubscripts=\relax} + +\def\setlowsubscripts + {\def\dosetsubscripts{\setsubscripts}} + +\setlowsubscripts + +\newcount\horchemical % t.z.t. \newcounter +\newcount\verchemical % t.z.t. \newcounter +\newcount\txtchemical % t.z.t. \newcounter +\newcount\levchemical % t.z.t. \newcounter + +\newif\ifinchemical \inchemicalfalse +\newif\iffixedchemical \fixedchemicalfalse + +\newbox\chemicalsymbols + +% Eigenlijk moeten de constanten en variabelen in cont-nl.tex +% staan. Dit pakket is echter relatief onafhankelijk van CONTEXT. + +\definesystemvariable {chemical} + +\definesystemconstant {chemical} + +\definesystemconstant {translate} +\definesystemconstant {distance} +\definesystemconstant {mirror} +\definesystemconstant {rotate} +\definesystemconstant {substitute} +\definesystemconstant {angle} + +\definesystemconstant {executechemical} +\definesystemconstant {chemicaltextelement} +\definesystemconstant {chemicallinesegment} +\definesystemconstant {chemicalcircsegment} + +\def\chemicalspace {\quad} + +% begin van experiment: +% +% De onderstaande twee macro's kunnen worden gebruikt voor +% bijvoorbeeld een interactiemechanisme. +% +% \localgotochemical {verwijzing} {tekst} +% \localthisischemical {verwijzing} + +\def\dowithchemical% + {} + +\doifdefinedelse{@@iastate} + {\def\localgotochemical#1#2{\naarbox{#2}[#1]}% + \def\localthisischemical#1{\pagereference[#1]}} + {\def\localgotochemical#1{}% + \def\localthisischemical#1{}} + +% eind van experiment + +\def\setchemicalmaximum #1 + {\def\maxchemical{#1}} + +\def\doifchemicalnumber#1#2#3% + {\doifnumberelse{#1} + {\ifnum#1>\maxchemical\relax + \writestatus{ppchtex}{number #1 is skipped}% + \else + #3% + \fi} + {\unknownchemical{#2}}}% + +\newif\ifsmallchemicaltext + +\let\@@localchemicalstyle\empty + +\def\setupchemicalformat[#1]% + {\processaction + [\getvalue{#1\c!size}] + [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]% + \processaction + [\getvalue{#1\c!textsize}] + [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]% + \processaction + [\getvalue{#1\c!scale}] + [ \v!small=>\def\@@localchemicalscale{500}, + \v!medium=>\def\@@localchemicalscale{625}, + \v!big=>\def\@@localchemicalscale{750}, + \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]} + +\def\@@currentchemicalformat + {\ifinchemical + \@@localchemicalformat + \else + \@@localchemicalstyle + \fi} + +\def\dosetupchemical[#1]% + {\getparameters[\??chemical\s!chemical][#1]% + \doifelse{\@@chemicalchemicaloffset}{LOW} + {\setlowsubscripts} + {\sethighsubscripts}% + \setupchemicalformat[\??chemical\s!chemical]% + \ignorespaces} + +\def\setupchemical + {\dosingleargument\dosetupchemical} + +\def\@@dochemicalstyle% % default mapping + {\@@chemicalstyle} + +\def\@@dochemicalcolor% % no mapping yet + {} + +\def\@@chemicalstyle % $inner-style$ % (overloaded) + {\@@chemicalchemicalstyle} % $$outer-style$$ + +\def\@@writechemicalstate#1#2% + {} + +\def\@@beginchemicallocalpicture + {\ifcase\chemicaldrawingmode + \beginpicture + \or + \pspicture(0,0)(0,0) % is this permitted ? + \or + \pushMPdrawing + \startMPdrawing + %prologues := 1 ; + %input mp-tool ; + u := 10*\@@chemicalunit; + bboxmargin := 0pt ; + pickup pencircle scaled 2u ; % ??? + \stopMPdrawing + \beginpicture + \fi} + +\def\@@endchemicallocalpicture#1#2% + {\ifcase\chemicaldrawingmode + \endpicture + \or + \endpspicture + \or + \resetchemicalcoordinates + \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}% + \wd2=\!!zeropoint + \ht2=\!!zeropoint + \dp2=\!!zeropoint + \put {\box2} at 0 0 + \endpicture + \popMPdrawing + \fi} + +\def\@@beginchemicalpicture#1#2#3#4% + {\ifnum\chemicaldrawingmode=1 + \pspicture(#1,#3)(#2,#4)% + \def\account##1##2{}% + \psaxes[axesstyle=none,labels=none,ticks=none](#1,#3)(#2,#4)% + \else + \beginpicture + \setplotarea + x from {#1} to {#2}, + y from {#3} to {#4} + \iffixedchemical + \accountingon + \def\account##1##2% + {\put {} at {##1} {##2} }% + \else + \accountingoff + \def\account##1##2{}% + \fi + \fi + \ignorespaces} + +\def\@@endchemicalpicture% + {\ifcase\chemicaldrawingmode + \put {\box\chemicalsymbols} at 0 0 % elders + \endpicture + \or + \rput(0,0){\box\chemicalsymbols}% + \endpspicture + \or + \put {\box\chemicalsymbols} at 0 0 % elders + \ifMPdrawingdone + \resetchemicalcoordinates + \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}% + \wd2=\!!zeropoint + \ht2=\!!zeropoint + \dp2=\!!zeropoint + \put {\box2} at 0 0 % + \fi + \endpicture + \fi} + +\def\@@setchemicalcoordinatesystem#1% + {\edef\@@chemicalunit{#1}% + \ifcase\chemicaldrawingmode + \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % + \or + \psset{unit=\@@chemicalunit}% + \or + \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % + \startMPdrawing + %input mp-tool ; + %prologues := 1 ; + u := 10*#1; + bboxmargin := 0pt ; + pickup pencircle scaled 2u ; % ??? + \stopMPdrawing + \fi} + +\ifx\MPdivten\undefined % hack to prevent overflows in mp + \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} +\fi + +\def\@@setchemicalaxis#1#2#3#4% + {\ifcase\chemicaldrawingmode + \axis + bottom shiftedto y=0 + ticks from {#1} to {#2} by 500 / + \axis + left shiftedto x=0 + ticks from {#3} to {#4} by 500 / % + \or + \psaxes[labels=none,Dx=500,Dy=500](0,0)(#1,#3)(#2,#4)% + \or + \global\MPdrawingdonetrue + % we need to div beforehand because of mp limitations + \startMPdrawing + x1 := \MPdivten[#1]u ; x2 := \MPdivten[#2]u; + y1 := \MPdivten[#3]u ; y2 := \MPdivten[#4]u; + draw z1--(x2,y1)--z2--(x1,y2)--cycle ; + d := 50u ; dd := 10u ; + draw (x1,0)--(x2,0) ; + draw (0,y1)--(0,y2) ; + for i=d step -d until x1: draw (i,dd)--(i,-dd) ; endfor ; + for i=d step d until x2: draw (i,dd)--(i,-dd) ; endfor ; + for i=d step -d until y1: draw (-dd,i)--(dd,i) ; endfor ; + for i=d step d until y2: draw (-dd,i)--(dd,i) ; endfor ; + \stopMPdrawing + \fi} + +\def\@@setsecondchemicalplotsymbol% + {\ifcase\chemicaldrawingmode + \!!widtha=50.8mm + \divide\!!widtha by \@@chemicalresolution\relax + \plotsymbolspacing=\!!widtha + \setplotsymbol({\vrule\!!height\!!widtha\!!width\!!widtha})% + \fi} + +% Something for Dirk: + +\newcount \currentchemical + +%\newif \ifskipchemical + +\def\setchemicaldimensions#1#2#3% + {\bgroup + \global\advance\currentchemical by 1 + \dimen0=#1\relax + \dimen2=#2\relax + \dimen4=#3\relax + \setxvalue{chemical::\the\currentchemical}% + {\noexpand\docommand{\the\dimen0}{\the\dimen2}{\the\dimen4}}% + \egroup} + +%\def\getchemicaldimensions#1#2#3% +% {\global\advance\currentchemical by 1 +% \def\docommand##1##2##3% +% {#1=##1\relax#2=##2\relax#3=##3\relax}% +% \doifdefinedelse{chemical::\the\currentchemical} +% {\getvalue{chemical::\the\currentchemical}} +% {\docommand{6cm}{4cm}{0cm}}} +% +%\def\savechemicaldimensions% +% {\bgroup +% \writestatus{ppchtex}{saving dimensions in ppchtex.dim}% +% \def\docommand##1##2##3% +% {\immediate\write\scratchwrite +% {\noexpand\setchemicaldimensions{##1}{##2}{##3}}}% +% \immediate\openout\scratchwrite=ppchtex.dim +% \scratchcounter=0 +% \loop +% \ifnum\scratchcounter<\currentchemical +% \advance\scratchcounter by 1 +% \getvalue{chemical::\the\scratchcounter}% +% \repeat +% \immediate\closeout\scratchwrite +% \egroup} +% +%\def\loadchemicaldimensions% oh, how nice it would be to use +% {\bgroup % one of the context read commands +% \global\currentchemical=0 +% \immediate\openin\scratchread=./ppchtex.dim +% \ifeof\scratchread +% \immediate\closein\scratchread +% \global\skipchemicalfalse +% \else +% \immediate\closein\scratchread +% \input ./ppchtex.dim\relax +% \ifnum\currentchemical>0 +% \writestatus{ppchtex}{loading dimensions from ppchtex.dim}% +% \global\skipchemicaltrue +% \else +% \global\skipchemicalfalse +% \fi +% \global\currentchemical=0 +% \global\let\savechemicaldimensions=\relax +% \fi +% \egroup +% \global\let\loadchemicaldimensions=\relax} + +\ifx\normalchemicalframe\undefined + \let\normalchemicalframe\hbox % hook for educational purposes +\fi + +\unexpanded\def\complexstartchemical[#1]% + {\copyparameters + [\??chemical][\??chemical\s!chemical] + [\c!width,\c!height,\c!left,\c!right,\c!top,\c!bottom, + \c!bodyfont,\c!size,\c!scale,\c!state,\c!frame,\c!axis,\c!factor, + \c!location,\c!option,\c!alternative,\c!resolution,\c!offset,\c!style, + \c!color,\c!rulecolor,\c!rulethickness]% + \getparameters + [\??chemical] + [#1]% + % + \setupchemicalformat[\??chemical]% + % + \ifnum\chemicaldrawingmode=2 + \resetMPdrawing + \fi + % + \doif{\@@chemicalalternative}{2} + {\@@setsecondchemicalplotsymbol}% + % + \doif{\@@chemicalaxis}\v!on + {\let\chemicalframe\hbox}% + % + \!!counta=250000 + \divide\!!counta by \@@localchemicalscale + \!!widtha=\@@chemicalbodyfont + \divide\!!widtha by \!!counta + \@@setchemicalcoordinatesystem{\the\!!widtha}% + % + % \!!counta = -x \!!countc = -y + % \!!countb = +x \!!countd = +y + % + \def\calculateaxis##1##2##3##4##5% + {##1=##3\relax + ##2=##4\relax + \ifnum##5=0 + \ifnum##3=0 + \ifnum##4=0 + ##1=2000 + ##2=2000 + \fi + \fi + \else + \ifnum##3=0 + \ifnum##4=0 + ##1=##5\relax + \divide##1 by 2 + ##2=##1\relax + \else + ##1=##5\relax + \advance##1 by -##2\relax + \fi + \else + \ifnum##4=0 + ##2=##5\relax + \advance##2 by -##1\relax + \fi + \fi + \fi}% + \fixedchemicalfalse + \doif\@@chemicalwidth\v!fit + {\edef\@@chemicalwidth + {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% + \fixedchemicaltrue}% + \doif\@@chemicalheight\v!fit + {\edef\@@chemicalheight + {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% + \fixedchemicaltrue}% + \doifelse\@@chemicallocation\v!intext + {\!!counta=0 \!!countb=0 + \!!counta=0 \!!countd=0 } + {\calculateaxis + \!!counta\!!countb + \@@chemicalleft\@@chemicalright\@@chemicalwidth + \calculateaxis + \!!countc\!!countd + \@@chemicalbottom\@@chemicaltop\@@chemicalheight}% + % + \edef\@@chemheight {\the\!!countc}% + \edef\@@chemdepth {\the\!!countd}% + \edef\@@chemicaltop {\the\!!countc}% + \edef\@@chemicalbottom{\the\!!countd}% + % + \doifinsetelse\v!on{\@@chemicalframe,\@@chemicalaxis} + {\def\@@chemicalborder{\chemicalframe}} + {\def\@@chemicalborder{\normalchemicalframe}}% + % + \setbox0=\hbox\bgroup % this was a \vbox which took \hsize + % + \@@beginchemicalpicture + {-\the\!!counta}{\the\!!countb} + {-\the\!!countc}{\the\!!countd}% + \doif{\@@chemicalstate}\v!start + {\doif\@@chemicalaxis\v!on + {\@@setchemicalaxis + {-\the\!!counta}{\the\!!countb} + {-\the\!!countc}{\the\!!countd}}}% + \doifelse\@@chemicaloption\v!test + {\def\@@writechemicalstate##1##2% + {\convertargument##2\to\ascii + \writestatus{##1}{\ascii}}} + {\def\@@writechemicalstate##1##2{}}% + \ignorespaces} + +\def\dostartchemical% + {\catcode`\^=\@@superscript% t.b.v. \enableduplication + \catcode`\_=\@@subscript % t.b.v. de zekerheid + \begingroup + \inchemicaltrue + \def\toptext##1{\gdef\thetoptext{##1}\ignorespaces}\toptext{}% + \def\bottext##1{\gdef\thebottext{##1}\ignorespaces}\bottext{}% + \def\midtext##1{\gdef\themidtext{##1}\ignorespaces}\midtext{}% + \def\@@chemicalpostponed{}% + \complexorsimpleempty\startchemical} + +\def\startchemical + {\bgroup % t.b.v. ungrouped floats +% \loadchemicaldimensions +% \ifskipchemical +% \def\dostartchemical% +% {\def\dummy[####1]{}\dosingleempty\dummy}% +% \def\chemical% +% {\def\dummy[####1][####2][####3]{}\dotripleempty\dummy}% +% \def\toptext##1{}% +% \def\midtext##1{}% +% \def\bottext##1{}% +% \fi + \dostartchemical} + +\def\stopchemical + {%\ifskipchemical + % \getchemicaldimensions{\dimen0}{\dimen2}{\dimen4}% + % \dimen8=\dimen2\advance\dimen8 by \dimen4 + % \setbox0=\vbox to \dimen8 + % {\vss\hbox to \dimen0{\hss\the\currentchemical\hss}\vss}% + % \wd0=\dimen0\ht0=\dimen2\dp0=\dimen4 + % \chemicalframe{\box0}% + %\else + \checkchemicalpicture + \@@endchemicalpicture + \egroup + \ifnum\chemicaldrawingmode=1 + \dimen0=\@@chemicalunit + \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}% + \ht0=\@@chemheight\dimen0 + \dp0=\@@chemdepth\dimen0 + \fi + \dimen0=\ht0 + \advance\dimen0 by \dp0 + \inchemicalfalse % enables \chemie{} in text + \setbox4=\alignedchemical\themidtext + \setbox6=\alignedchemical\thetoptext + \setbox8=\alignedchemical\thebottext + \setbox4=\hbox to \wd0 + {\strut\hss$\vcenter{\box4}$\hss}% + \setbox2=\vbox to \dimen0 + {\hbox to \wd0{\strut\hss\box6\hss} + \vfill + \hbox to \wd0{\strut\hss\box8\hss} + \vss}% disables the depth + \wd0=0pt \wd4=0pt + \ht2=\ht0 \dp2=\dp0 + \ht4=\ht0 \dp4=\dp0 + %\setchemicaldimensions{\wd2}{\ht2}{\dp2}% + \@@chemicalborder{\box0\box4\box2}% text on top of chemicals + \endgroup + %\fi + \ignorespaces + \egroup} % t.b.v. ungrouped floats + +\def\alignedchemical#1% + {\vtop + {\def\par{\egroup\hbox\bgroup\strut}% + \let\\=\par + \let\endgraf=\par + \hbox\bgroup\strut#1\egroup}} + +% \setchemicalcoordinates{#1}{#2} +% +% #1: verplaatsing in x-richting +% #2: verplaatsing in y-richting + +\newif\ifchemicaldirection + +\def\checkchemicaldirection#1#2% + {\ifchemicaldirection + \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi + \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi + \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi + \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi + \chemicaldirectionfalse + \fi} + +\def\processchemicaldirection% + {\chemicaldirectiontrue\processchemicaltranslate} + +\def\setchemicalcoordinates#1#2% + {\advance\horchemical #1\relax + \advance\verchemical #2\relax + \checkchemicaldirection{#1}{#2}% + \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}% + \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\resetchemicalcoordinates + {\horchemical=0 + \verchemical=0 + \edef\chemicalxoffset{0}% + \edef\chemicalyoffset{0}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at 0 0 + \fi} + +\def\restorechemicalcoordinates + {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}% + \edef\chemicalxoffset{\the\horchemical}% + \edef\chemicalyoffset{\the\verchemical}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\setchemicaltranslate #1 #2 #3 + {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}} + +\def\processchemicaltranslate#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{MOV#1} + {\ifnum##1=0 + \def\chemicaloffset{0}% incompatible change + \resetchemicalcoordinates + \else + \getvalue{\s!translate##1}% + \dochemicaloffset{##1}% + \def\chemicaloffset{0}% + \fi}}% + \doprocess[#1]} + +\def\setchemicaldistance #1 + {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\setchemicaldirection #1 + {\def\chemicaldirection{#1}} + +\def\processchemicaldistance#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{ADJ#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!distance##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +\def\setchemicalsubstitute #1 + {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\processchemicalsubstitute#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{SUB#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +% Het is mogelijk een offset of move meerdere malen uit te +% voeren, door een nummer voor het commando te plaatsen. + +\def\chemicalrepeat {1} + +\def\redoprocesschemical[#1#2]% + {\doifinstringelse{#1}{0123456789.} + {\edef\chemicalrepeat{\chemicalrepeat#1}% + \redoprocesschemical[#2]} + {\processchemical[#1#2]% + \def\chemicalrepeat{1}}} + +\def\doprocesschemical[#1#2]#3% + {\doifinstringelse{#1}{0123456789.} + {\def\chemicalrepeat{#1}% + \redoprocesschemical[#2]} + {#3}} + +% \dochemicaloffset{#1} +% +% #1: binding + +\def\chemicaloffset{0} + +\def\processchemicaloffset#1% + {\dimen0=62500 sp % real calc on cardinals, funny number + \dimen0=\chemicalrepeat\dimen0 + \divide\dimen0 by \@@localchemicalscale + \!!counta=\dimen0 + \def\doprocess[##1##2]% + {\doifinstringelse{##1}{128} + {\edef\chemicaloffset{\the\!!counta}} + {\doifinstringelse{##1}{456} + {\edef\chemicaloffset{-\the\!!counta}} + {\doifelse{##1}{0} + {\edef\chemicaloffset{0}} + {\unknownchemical{OFF#1}}}}}% + \doprocess[#1]} + +\def\dochemicaloffset#1% + {\ifnum\chemicaloffset=0 + \def\undochemicaloffset{}% + \else + \setchemicalcoordinates{-\chemicaloffset}{0}% + \def\undochemicaloffset% + {\setchemicalcoordinates{\chemicaloffset}{0}% + \def\undochemicaloffset{}}% + \fi} + +\def\processchemicalphantom#1#2% + {\setbox0=\hbox + {\def\splitoff##1????{##1}% + $\@@dochemicalstyle{\@@localchemicalformat\splitoff#2}$}% + \dimen0=.25\wd0 + \divide\dimen0 by \@@localchemicalscale + \!!counta=\dimen0 + \doifinstringelse{#1}{128} + {\edef\chemicaloffset{\the\!!counta}} + {\doifinstringelse{#1}{456} + {\edef\chemicaloffset{-\the\!!counta}} + {\doifelse{#1}{0} + {\edef\chemicaloffset{0}} + {\unknownchemical{OF#1:#2}}}}} + +% \dosetchemicalrotation{#1}{#2} +% +% #1: cos(phi) +% #2: sin(phi) + +\def\chemicalrotation {1} +\def\chemicalangle {0} +\def\chemicalxoffset {0} +\def\chemicalyoffset {0} + +\def\setchemicalmirror#1% + {\setvalue{\s!mirror#1}{*}} + +\def\resetchemicalmirror#1% + {\resetvalue{\s!mirror#1}} + +\def\togglechemicalmirror#1% + {\doifelse{\getvalue{\s!mirror#1}}{*} + {\resetchemicalmirror{#1}} + {\setchemicalmirror{#1}}} + +\def\setchemicalrotation #1 #2 #3 #4 #5 #6 #7 #8 #9 + {\setvalue{\s!rotate1.#1}{\dosetchemicalrotation{#2}{#3}}% + \setvalue{\s!rotate2.#1}{\dosetchemicalrotation{#4}{#5}}% + \setvalue{\s!rotate3.#1}{\dosetchemicalrotation{#6}{#7}}% + \setvalue{\s!rotate4.#1}{\dosetchemicalrotation{#8}{#9}}} + +\def\setchemicalangle #1 #2 #3 #4 #5 + {\setvalue{\s!angle1.#1}{\dosetchemicalangle{#2}}% + \setvalue{\s!angle2.#1}{\dosetchemicalangle{#3}}% + \setvalue{\s!angle3.#1}{\dosetchemicalangle{#4}}% + \setvalue{\s!angle4.#1}{\dosetchemicalangle{#5}}} + +\def\chemicalrotate[#1]% + {\doifdefinedelse{\s!mirror#1} + {\getvalue{\s!rotate\chemicalrotation.#1\getvalue{\s!mirror#1}}% + \getvalue{\s!angle\chemicalrotation.#1\getvalue{\s!mirror#1}}} + {\getvalue{\s!rotate\chemicalrotation.#1}% + \getvalue{\s!angle\chemicalrotation.#1}}} + +\def\dosetchemicalangle#1% zwak zie onder + {\def\chemicalangle{#1}} + +\def\dosetchemicalrotation#1#2% + {\ifnum\chemicaldrawingmode=1 + % njet + \else + \startrotation by {#1} {#2} %% \stoprotation (t.b.v. testen) + \fi} + +\def\doresetchemicalrotation + {\ifnum\chemicaldrawingmode=1 + % njet + \else + \stoprotation + \fi} + +\def\processchemicalrotation#1% + {\def\doprocess[##1##2]% + {\doifnumberelse{##1} + {\def\chemicalrotation{##1}} + {\unknownchemical{ROT#1}}}% + \doprocess[#1]} + +% \filtertextelement[#1][#2][#3][#4] +% +% #1: volgnummer +% #2: offset in uitlijningen +% #3: lijst met uitlijningen -> \chemicalloca +% #4: lijst met teksten -> \chemicaltext + +\def\setchemicallocation#1% + {\doifelse{#1}{} + {\edef\chemicalloca{c}} + {\edef\chemicalloca{#1}}} + +\newif\iffixedchemicaltext + +\def\filterchemicaltextelement[#1][#2][#3][#4]% + {\ifchemicaltextconstant + \def\chemicaltext{#4}% + \setchemicallocation{}% + \else + \ifnum#1=0\relax + \setchemicallocation{}% + \else + \iffixedchemicaltext + \!!counta#2 + \else + \!!counta=\chemicalrotation + \advance\!!counta -1 + \multiply\!!counta #2 + \advance\!!counta #1 + \fi + \getfromcommalist[#3][\the\!!counta]% + \setchemicallocation\commalistelement + \fi + \ifchemicalpicture + \let\chemicaltext\relax + \else + \advance\txtchemical 1 + \getfromcommalist[#4][\txtchemical]% + \let\chemicaltext\commalistelement + \fi + \fi + \fixedchemicaltextfalse} + +% \putchemicaltext{#1}{#2} +% +% #1 : x-coordinaat +% #2 : y-coordinaat +% +% \chemicaltext en \chemicalloca worden met \gettextelement +% opgehaald uit de tweede set bij \chemie +% +% Ten behoeve van testdoeleinden wordt gebruik gemaakt van +% \chemicalframe in plaats van het meer sjieke, maar tevens +% meer trage \framed. + +\ifx\ruledhbox\undefined + \def\chemicalframe#1% + {\hbox + {\vrule\hskip-.4pt + \vbox{\hrule\vskip-.4pt\hbox{#1}\vskip-.4pt\hrule}% + \hskip-.4pt\vrule}} +\else + \def\chemicalframe#1% + {\ruledhbox{#1}} +\fi + +\def\doputchemicaltext#1 [#2] at #3 #4 % + {\ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[#2]{\chemicalangle}(#3,#4){#1}}}% + \else + \put {#1} [#2] at {#3} {#4} % + \fi} + +\def\dodoifsinglelocation#1#2\\#3% + {\ifx#2\relax#3\fi} + +\def\doifsinglelocationelse#1% + {\expandafter\dodoifsinglelocationelse#1\relax\\} + +\def\putchemicaltext#1#2% + {\enablechemicalspecials + \ifchemicalpicture + \setchemicalpicture{#1}{#2}% + \else + \doifelse\@@chemicaloption\v!test + {\def\@@chemicalframe{\chemicalframe}} + {\def\@@chemicalframe{}}% + \dosetsubscripts + \setbox2=\hbox{\@@dochemicalcolor + $\@@dochemicalstyle{\@@localchemicalformat \chemicaltext}$}% + \setbox4=\hbox{$\@@dochemicalstyle{\@@localchemicalformat C_2^2}$}% + \setbox6=\hbox{$\@@dochemicalstyle{\@@localchemicalformat O}$}% or C + \doresetsubscripts + \doifnot\@@chemicallocation\v!intext + {\ht2=\ht4 + \dp2=\dp4}% + \setbox2=\hbox{\@@chemicalframe{\box2}}% + \ifdim\wd2>\wd6 + \doifelse{#1}{0} + {\doifnot{#2}{0}{\wd2=\wd6}} + {%\doifsinglelocation\chemicalloca + {\doifinset{\chemicalloca}{t,b}{\wd2=\wd6}}}% common ? + \fi + \expanded + {\doputchemicaltext + {\noexpand\dowithchemical{\copy2}} % per se \copy2 i.p.v. \box2 + [\chemicalloca] at {#1} {#2} } + \nomoreaccounting + \fi + \disablechemicalspecials} + +\def\setchemicaltextelement #1 #2 #3 + {\setvalue{\s!chemicaltextelement#1}{\putchemicaltext{#2}{#3}}} + +\def\getchemicalfixedtextelement% + {\fixedchemicaltexttrue + \getchemicaltextelement} + +\def\getchemicaltextelement[#1][#2][#3][#4][#5]% + {\filterchemicaltextelement[#2][#3][#4][#5]% + \doifelse{#2}{0} + {\dochemicaloffset{#2}% % incompatible change + \putchemicaltext{0}{0}% + \undochemicaloffset} % incompatible change + {\chemicalrotate[#2]% + \dochemicaloffset{#2}% + \def\chemicaltextelementnumber{#2}% + \getvalue{\s!chemicaltextelement#1}% + \getvalue{\s!chemicaltextelement#11}% + \getvalue{\s!chemicaltextelement#12}% + \getvalue{\s!chemicaltextelement#13}% + \undochemicaloffset}} + +\def\processchemicaltextelement#1#2#3#4#5% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicaltextelement[#1][##1][#4][#5][#3]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicaltextelement[#1][##1][#4][#5][#3]% + \doifnot{##2}{?}{\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]% + \smallchemicaltextfalse} + +\def\processchemicalsmalltextelement% + {\smallchemicaltexttrue\processchemicaltextelement} + +\def\processchemicalsmalltextconstant% + {\smallchemicaltexttrue\processchemicaltextconstant} + +\def\processchemicalunrotatedtextelement#1#2#3#4#5#6% + {\bgroup + \xdef\@@xxx{0}% + \xdef\@@yyy{0}% + \def\putchemicaltext##1##2% + {\xdef\@@xxx{##1}% + \xdef\@@yyy{##2}}% + \getvalue{\s!chemicaltextelement#1}% + \egroup + \bgroup + \def\doputchemicaltext##1 [##2] at ##3 ##4 % + {\ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\rput{\chemicalangle}(\@@xxx,\@@yyy){\expanded{\rput[##2](##3,##4){##1}}}}% + \else + \put + {\stoprotation \setcoordinatesystem point at 0 0 + \expanded{\put {##1} [##2] at {##3} {##4} }} + at {\@@xxx} {\@@yyy} + \fi}% + \processchemicaltextelement{#2}{#3}{#4}{#5}{#6}% + \egroup} + +\newif\ifchemicaltextconstant + +\def\processchemicaltextconstant#1#2#3#4% + {\chemicaltextconstanttrue + \let\@@oldchemicalframe\@@chemicalframe + \let\@@chemicalframe\relax + \processchemicaltextelement{#1}{#2}{#3}{#4}{}% + \let\@@chemicalframe\@@oldchemicalframe + \chemicaltextconstantfalse} + +% \plotchemicalline{#1}{#2}{#3}{#4} +% +% #1: x-coordinaat beginpunt +% #2: y-coordinaat beginpunt +% #3: x-coordinaat eindpunt +% #4: y-coordinaat eindpunt + +\chardef\chemicallinetype=0 + +\def\doplotchemicalline + {\!!counte=\!!countc \advance\!!counte by -\!!counta + \!!countf=\!!countd \advance\!!countf by -\!!countb + \bgroup + \ifcase\chemicaldrawingmode + \ifcase\chemicallinetype + % 0 : normal line + \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% + \or + % 1 : normal arrow + \arrow <5pt> [.2,.67] from {\!!counta} {\!!countb} to {\!!countc} {\!!countd} + \or + % 2 : reverse arrow + \arrow <5pt> [.2,.67] from {\!!countc} {\!!countd} to {\!!counta} {\!!countb} + \or + % 3 : unrotated line + \put {\stoprotation \setcoordinatesystem point at 0 0 + \plot 0 0 {\!!counte} {\!!countf} /} + [\chemicallineposition] at {\!!counta} {\!!countb} + \else + % 4 : dashed line + \findlength {\plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /}% + \setdashesnear <2pt> for <\totalarclength>% + \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% + \fi + \or + \ifcase\chemicallinetype + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline{->}(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline{<-}(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicallineposition]{-\chemicalangle}% + (\!!counta,\!!countb){\psline(0,0)(\!!counte,\!!countf)}}}% + \else + \psset{linestyle=dashed}% + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \fi + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + x3 := \MPdivten[\the\!!counte]u ; + y3 := \MPdivten[\the\!!countf]u ; + \ifcase\chemicallinetype + % 0 : normal line + draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 1 : normal arrow + drawarrow ((z1--z2) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 2 : reverse arrow + drawarrow ((z2--z1) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 3 : unrotated line % nog \chemicalineposition: t/b + draw (origin--z3) + shifted (z1 rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \else + % 4 : dashed line + draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) +% shifted z0 dashed evenly ; + shifted z0 dashed dashpattern(on 5.5u off 6u) ; + \fi + \stopMPdrawing + \fi + \egroup + \account\!!counta\!!countb + \account\!!countc\!!countd} + +\def\plotchemicalline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \doplotchemicalline} + +\def\plotchemicalfactorline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifdim\@@chemicalfactor\onepoint=\onepoint \else + \scratchdimen\!!counta\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!counta\scratchdimen + \scratchdimen\!!countc\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!countc\scratchdimen + \fi + \doplotchemicalline} + +\def\plotchemicalzline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + filldraw (( + \ifnum\chemicalangle>180 + z1--z2 + \else\ifnum\chemicalangle<90 + z1--(z2 shifted (-2u,+2u))--(z2 shifted (+2u,-2u)) + \else\ifnum\chemicalangle=90 + (z1 shifted (-2u,+2u))--(z1 shifted (+2u,-2u))-- + (z2 shifted (+2u,+2u))--(z2 shifted (-2u,-2u)) + \else + (z1 shifted (+2u,+2u))--(z1 shifted (-2u,-2u))--z2 + \fi\fi\fi + --cycle) rotatedaround(origin,-\chemicalangle)) shifted z0 ; + \stopMPdrawing + \else + \doplotchemicalline + \ifnum\chemicalangle>180 \else + \ifnum\chemicalangle=90 + \advance\!!counta by -20 \advance\!!countc by -20 + \doplotchemicalline + \advance\!!counta by 40 \advance\!!countc by 40 + \else\ifnum\chemicalangle<90 + \advance\!!countc by -20 \advance\!!countd by +20 + \doplotchemicalline + \advance\!!countc by +40 \advance\!!countd by -40 + \else + \advance\!!counta by 20 \advance\!!countb by 20 + \doplotchemicalline + \advance\!!counta by -40 \advance\!!countb by -40 + \fi\fi + \fi + \doplotchemicalline + \fi} + +\def\plotchemicaldeltaline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + filldraw ((z1--(z2 rotatedaround(z1,5))--(z2 rotatedaround(z1,-5)) + --cycle) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\setchemicallinesegment #1 #2 #3 #4 #5 + {\setvalue{\s!chemicallinesegment#1}{\plotchemicalline{#2}{#3}{#4}{#5}}} + +\def\setchemicalfactorlinesegment #1 #2 #3 #4 #5 + {\setvalue{\s!chemicallinesegment#1}{\plotchemicalfactorline{#2}{#3}{#4}{#5}}} + +\def\getchemicallinesegment[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \getvalue{\s!chemicallinesegment#2}% + \getvalue{\s!chemicallinesegment#21}% + \getvalue{\s!chemicallinesegment#22}% + \undochemicaloffset} + + +\def\getprivatechemicallinesegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicallinesegment#2#1}} + +\def\doprocesschemicallinesegment#1#2#3#4#5% + {\chardef\chemicallinetype=#1 + \def\chemicallineposition{#2}% + \def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#4#5} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#4#5} + {#3[##1][#4]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {#3[##1][#4]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#5]} + +\def\processchemicallinesegment + {\doprocesschemicallinesegment0c\getchemicallinesegment} + +\def\processchemicalzlinesegment#1#2% + {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \bgroup + \def\plotchemicalline{\plotchemicalzline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicaldeltalinesegment#1#2% + {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \bgroup + \def\plotchemicalline{\plotchemicaldeltaline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processprivatechemicallinesegment% + {\doprocesschemicallinesegment0c\getprivatechemicallinesegment} + +\def\processchemicaldownarrowsegment% + {\doprocesschemicallinesegment1c\getchemicallinesegment} + +\def\processchemicaluparrowsegment% + {\doprocesschemicallinesegment2c\getchemicallinesegment} + +\def\processchemicalunrotatedlinesegment#1% + {\doprocesschemicallinesegment3{#1}\getchemicallinesegment} + +\def\processchemicaldashedlinesegment% + {\doprocesschemicallinesegment4c\getchemicallinesegment} + +\def\processchemicalopenend#1#2% + {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}} + +\def\doprocesschemicalopenend[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \ifcase\chemicaldrawingmode + \beginpicture + \setquadratic\plot + 300 0 400 0 + 500 0 550 75 + 600 0 650 -75 + 700 0 750 75 + 800 0 850 -75 + 900 0 950 0 + 1050 0 / + \endpicture + \or + \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(300,0)(500,0)% + \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}% + \psline(950,0)(1050,0)}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw + (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u).. + (60.0u,0)..(65.0u,-7.5u)..(70.0u,0).. + (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up} + (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \fi + \undochemicaloffset} + +% \plotchemicalcircle{#1}{#2}{#3}{#4} +% +% #1: lengte van de boog in graden +% #2: x-coordinaat eindpunt +% #3: y-coordinaat eindpunt + +\newif\ifchemicaldotted + +\def\plotchemicalcircle#1#2#3#4#5#6% + {\bgroup + \ifcase\chemicaldrawingmode + \ifchemicaldotted + \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }% + \divide\totalarclength by 6 + \def\b{\the\totalarclength}% + \divide\totalarclength by 2 + \def\a{\the\totalarclength}% + \setdashpattern <\a,\b,\b,\b,\b,\b,\a> + \fi + \circulararc {#4} degrees from {#5} {#6} center at {0} {0} % + \or + \ifchemicaldotted + \psset{linestyle=dashed}% + \fi + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psarc(0,0){#3}{#1}{#2}}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + r := \MPdivten[#3]*2u; + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r))) + rotatedaround (origin,\chemicalangle+150)) + shifted z0 \ifchemicaldotted dashed withdots \fi ; + \stopMPdrawing + \fi + \egroup} + +\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7 + {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}} + +\def\getchemicalcircsegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicalcircsegment#2}} + +\def\doprocesschemicalcircsegment#1#2% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]} + +\def\processchemicalcircsegment% + {\chemicaldottedfalse\doprocesschemicalcircsegment} + +\def\processchemicaldottsegment% + {\chemicaldottedtrue\doprocesschemicalcircsegment} + +\let\endchemicalpicture = \relax +\let\checkchemicalpicture = \relax +\let\nomoreaccounting = \relax + +\newif\ifchemicalpicture + +\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET + {\checkchemicalpicture + \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT + \chemicalpicturetrue + \processchemical[#1]} + +\def\setchemicalpicture#1#2% + {\chemicalpicturefalse + \def\endchemicalpicture% + {\@@endchemicallocalpicture{#1}{#2}% + \egroup + \ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}% + \else + \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} } + \fi + \egroup}% + \def\checkchemicalpicture% + {\ifx\endchemicalpicture\relax \else + \writestatus{ppchtex}{missing end of picture (PE)}% + \endchemicalpicture + \fi}% + \setbox\nextbox=\hbox\bgroup + \@@beginchemicallocalpicture + % alternatief: gewoon accounting, en zelf l,r afhandelen + \ifnum\chemicaldrawingmode=1 + % njet + \else + \accountingon + \let\nomoreaccounting=\accountingoff + \fi} + +\def\doskipchemical[#1][#2]% + {{\tt[ppchtex]}} + +\def\skipchemical% + {\dodoubleargument\doskipchemical} + +\def\complexchemical% met \expandafter + {\ifinchemical + \expandafter\dochemical + \else + \writestatus{ppchtex}{the [][]-alternative is not permitted here}% + \expandafter\skipchemical + \fi} + +\newif\ifinnerchemical + +\def\dosimplechemical#1#2#3% + {\doifdefinedelse{\??chemical\c!location} + {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}} + {\ifinnerchemical + \let\chemicalsign = \chemicalinnersign + \let\chemicalmolecule = \chemicalinnermolecule + \let\chemicalsinglearrow = \chemicalsingleinnerarrow + \let\chemicaldoublearrow = \chemicaldoubleinnerarrow + \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow + \else + \let\chemicalsign = \chemicaloutersign + \let\chemicalmolecule = \chemicaloutermolecule + \let\chemicalsinglearrow = \chemicalsingleouterarrow + \let\chemicaldoublearrow = \chemicaldoubleouterarrow + \let\chemicaltwintiparrow = \chemicaltwintipouterarrow + \fi + \disablechemicalspecials + \unexpandedprocessallactionsinset + [#1] + [ HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + PLUS=>\chemicalsign{+}, + GIVES=>\chemicalsinglearrow{#2}{#3}, + EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3}, + MESOMERIC=>\chemicaltwintiparrow{#2}{#3}, + SINGLE=>\singlechemicalbond, + DOUBLE=>\doublechemicalbond, + TRIPLE=>\triplechemicalbond, + +=>\chemicalsign{+}, + ->=>\chemicalsinglearrow{#2}{#3}, + <->=>\chemicaldoublearrow{#2}{#3}, + <>=>\chemicaltwintiparrow{#2}{#3}, + -=>\singlechemicalbond, + --=>\doublechemicalbond, + ---=>\triplechemicalbond, + \s!unknown=>\enablechemicalspecials + \chemicalmolecule{\commalistelement}{#2}{#3}]}} + +%\def\dosimplechemicalA#1#2#3% +% {\let\chemicalspace=\relax +% \def\dodosimplechemical##1% +% {\dosimplechemical{##1}{}{}}% +% \@EA\processcommalist\@EA[\@@chemicalchemicaloffset,#1]\dodosimplechemical +% \egroup} + +\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax} + {\let\chemicalspace=\relax + \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalB#1#2#3% + {\dosimplechemical{#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalC#1#2#3% + {$\simplechemical{#1}{#2}{#3}$% + \egroup} % erbij + +\def\simplechemical + {\ifinner + \innerchemicaltrue + \else + \innerchemicalfalse + \fi + \bgroup + \catcode`\^=\@@superscript % t.b.v. \enableduplication + \catcode`\_=\@@subscript % t.b.v. de zekerheid + \ifmmode + \ifinnerchemical + \def\next{\dotriplegroupempty\dosimplechemicalA}% + \else + \def\next{\dotriplegroupempty\dosimplechemicalB}% + \fi + \else + \def\next{\dotriplegroupempty\dosimplechemicalC}% + \fi + \next} + +\definecomplexorsimple\chemical + +\def\dogotochemical#1#2% + {\def\dowithchemical% % experiment + {\localgotochemical{#1}}% % experiment + \chemical} % experiment + +\def\gotochemical% % experiment + {\dosingleargument\dogotochemical} % experiment + +\def\dododochemical#1[#2][#3]% % experiment + {\def\simpledododochemical% % experiment + {#1[#2][#3]}% % experiment + \def\complexdododochemical[##1]% % experiment + {\def\dowithchemical% % experiment + {\localthisischemical{#2}}% % experiment + #1[#3][##1]}% % experiment + \complexorsimple\dododochemical} % experiment + +\def\dodochemical[#1][#2]% + {\ignorespaces + \ifinchemical + \drawchemical[#1][#2]% + \ignorespaces + \else + \startchemical[\c!location=\v!intext]% + \drawchemical[#1][#2]% + \expandafter\stopchemical + \fi + \ignorespaces} + +\def\dochemical[#1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[#1][]}% + \dodochemical[#1][]}% + % + \def\complexdochemical[##1]% + {\@@writechemicalstate{ppchtex}{[#1][##1]}% + \txtchemical=0% + \dodochemical[#1][##1]}% + % + \def\complexdochemical[##1]% % experiment + {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment + \txtchemical=0% % experiment + \dododochemical\dodochemical[#1][##1]}% % experiment + % + \complexorsimple\dochemical} + +% \processlocalchemicals{#1} +% +% #1: commando's + +\def\dodoprocesschemical#1% + {\processchemical[#1????]} + +\def\processlocalchemicals#1% + {\processcommalist[#1]\dodoprocesschemical} + +% \drawchemical[#1][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\localdodochemical[#1][#2]% + {\@@writechemicalstate{ppchtex}{[#1][#2]}% + %\bgroup % koppelen en afmetingen gaat fout, vandaar: + \advance\levchemical 1 + \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical + \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}% + \txtchemical=0 + \dodochemical[#1][#2]% + % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname + \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname + \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname + \advance\levchemical -1 + %\egroup + \ignorespaces} + +\def\drawchemical[#1][#2]% + {\ignorespaces + \def\dodochemical[##1][##2]% + {\drawchemical[##1][##2]% + \ignorespaces}% + \def\dochemical[##1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[##1][#2]}% + \dodochemical[##1][#2]% + \ignorespaces}% + \def\complexdochemical[####1]% + {\dododochemical\localdodochemical[##1][####1,#2]}% + \complexorsimple\dochemical}% + \doif\@@chemicalstate\v!start + {\doifelse\chemicalname\s!unknown + {\getvalue{\s!executechemical\defaultchemical}[#2]} + {\getvalue{\s!executechemical\chemicalname}[#2]}% + \def\unknownchemical##1% + {\processunknownchemical[##1][#2]}% + \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}% + \ignorespaces} + +\unexpanded\def\chemicaloxidation#1#2#3% + {\chemicaltop + {\ifnum#20=0 + 0% + \else + #1\expandafter\uppercase\expandafter{\romannumeral#2}% + \fi} + {#3}} + +\def\chemicaltfraction{\ifinchemical.60\else.8\fi} +\def\chemicalbfraction{\ifinchemical.45\else.6\fi} +\def\chemicallfraction{\ifinchemical.1\else.1\fi} +\def\chemicalrfraction{\ifinchemical.1\else.1\fi} + +\def\chemicaltighttext + {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}% + \def\chemicalbfraction{\ifinchemical.2\else.4\fi}% + \def\chemicallfraction{\ifinchemical 0\else 0\fi}% + \def\chemicalrfraction{\ifinchemical 0\else 0\fi}} + +\def\dochemicaltop#1#2#3#4% + {\vbox + {\@@dochemicalcolor + \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}} + +\def\dochemicalbottom#1#2#3#4% + {\vtop + {\@@dochemicalcolor + \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}} + +\def\chemicalleft#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle#1}$% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalright#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + $\@@dochemicalstyle{\scriptscriptstyle#1}$}} + +\def\chemicalcentered#1% + {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \dimen0=.5\ht2 + \advance\dimen0 by -.5\ht0 + \advance\dimen0 by \dp0 + \hbox{\@@dochemicalcolor\raise\dimen0\box0}} + +\def\chemicalleftcentered#1#2% + {\hbox + {\@@dochemicalcolor + \chemicalcentered{#1}% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalrightcentered#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + \chemicalcentered{#1}}} + +\def\chemicaltop {\dochemicaltop \hss \hss } +\def\chemicallefttop {\dochemicaltop \relax \hss } +\def\chemicalrighttop {\dochemicaltop \hss \relax} +\def\chemicalbottom {\dochemicalbottom \hss \hss } +\def\chemicalleftbottom {\dochemicalbottom \relax \hss } +\def\chemicalrightbottom {\dochemicalbottom \hss \relax} + +\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}} +\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}} +\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}} +\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}} + +\def\chemicalsmashedleft#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \wd2=\wd0 + \box2 + \egroup} + +\def\chemicalsmashedmiddle#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox{\hskip-.5\wd2\hskip.5\wd0\box2} + \egroup} + +\def\chemicalsmashedright#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}% + \egroup} + +\def\+{\tabalign} % is \long in Plain + +\def\chemicalforever#1#2% + {\bgroup + \setbox0=\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}% + \wd0=0pt + \big#1_{\hskip.1em\box0}% + \egroup} + +\def\disablechemicalspecials% + {\def\+##1{##1}\def\-##1{##1}% + \def\[{[}\def\]{]}% + \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}% + \def\X{}% + \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}% + \def\TL{}\def\BL{}\def\TR{}\def\BR{}% + \def\LT{}\def\LB{}\def\RT{}\def\RB{}% + \def\SL{}\def\SM{}\def\SR{}} + +\def\enablechemicalspecials% + {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed! + \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed! + \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed! + \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed! + \def\1{\chemicaloxidation\relax1}% + \def\2{\chemicaloxidation\relax2}% + \def\3{\chemicaloxidation\relax3}% + \def\4{\chemicaloxidation\relax4}% + \def\5{\chemicaloxidation\relax5}% + \def\6{\chemicaloxidation\relax6}% + \def\7{\chemicaloxidation\relax7}% + \def\X{\chemicaltighttext}% + \def\T{\chemicaltop}% + \def\B{\chemicalbottom}% + \def\L{\chemicalleft}% + \def\LC{\chemicalleftcentered}% + \def\R{\chemicalright}% + \def\RC{\chemicalrightcentered}% + \def\TL{\chemicaltopleft}% + \def\BL{\chemicalbottomleft}% + \def\TR{\chemicaltopright}% + \def\BR{\chemicalbottomright}% + \def\LT{\chemicallefttop}% + \def\LB{\chemicalleftbottom}% + \def\RT{\chemicalrighttop}% + \def\RB{\chemicalrightbottom}% + \def\SL{\chemicalsmashedleft}% + \def\SM{\chemicalsmashedmiddle}% + \def\SR{\chemicalsmashedright}} + +% \reversechemical#1#2#3 +% +% #1: prefix +% #2: volgnummer enz +% #3: tegengestelde volgnummers + +\def\reversechemical#1#2#3% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{#1#2}% + {\getfromcommalist[#3][##1]% + \let\reversechemicalaction=\commalistelement + \processchemical[#1\reversechemicalaction##2]}}% + \doprocess[#2]} + +% \processunknownchemical[#1????][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\defaultchemical% + {SIX} + +\def\processunknownchemical[#1????][#2]% + {\processaction + [#1] + [ SAVE=>\executechemicalSAVE, + RESTORE=>\executechemicalRESTORE, + HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + \s!default=>, + \s!unknown=>\doifdefinedelse{\s!executechemical#1} + {\def\chemicalrotation{1}% + \def\chemicaloffset{0}% + \doifdefined{\s!executechemical#1} + {\getvalue{\s!executechemical#1}[#2]}% + \@@chemicalpostponed} + {\getpredefinedchemical{#1}}]} + +\newcount\chemicalstack % tzt \newwounter + +\setvalue{\s!chemical\c!x1}{0} +\setvalue{\s!chemical\c!y1}{0} + +\def\executechemicalSAVE + {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}% + \advance\chemicalstack by 1 + \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname + %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed + \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}% + \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}} + +\def\restorechemicalvalues#1% + {\let\oldprocesschemical=\processchemical + \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}% + \let\processchemical=\oldprocesschemical} + +\def\executechemicalRESTORE + {\ifnum\chemicalstack=0\relax + \horchemical=\getvalue{\s!chemical x1}\relax + \verchemical=\getvalue{\s!chemical y1}\relax + \else + \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}% + %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname + \let\@@chemicalpostponed=\relax + \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax + \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax + \advance\chemicalstack by -1 + \fi + \restorechemicalcoordinates} + +% De onderstaande macro's zijn verantwoordelijk voor het zetten +% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog +% gehaald. Dit oogt m.i. fraaier. + +\def\chemicalinnerclip#1% + {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}} + +\def\chemicalraise#1#2% + {\chemicalinnerclip + {\setbox0=\hbox{$#1+$}% + \raise\dp0\hbox{$#1#2$}}} + +\def\chemicalinnersign#1% todo: \@@chemicaltextcolor + {\chemicalraise{\@@localchemicalstyle}{#1}} + +\def\chemicaloutersign#1% + {\chemicalraise{}{\@@dochemicalcolor#1}} + +\def\chemicalsingleinnerarrow#1#2% + {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}} + +\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\lower.2ex\hbox + {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}% + \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}% + \wd0=0pt\raise\ht0\box0\box2}}} + +\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}% + \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}% + \wd0=0pt\box0\box2}} + +\def\dochemicalouterarrow#1#2#3% + {\bgroup + \setbox0=\hbox{$\longrightarrow$}% + \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}% + \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}% + \dimen2=\wd0 % \dimen0 is used elsewhere + \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi + \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi + \chemicaloutermolecule + {#1} + {\ifdim\ht2>\!!zeropoint\box2\fi} % expands to \empty in test + {\ifdim\ht4>\!!zeropoint\box4\fi}% % expands to \empty in test + \egroup} + +\def\chemicalsingleouterarrow + {\dochemicalouterarrow + {\hbox to \dimen2{\rightarrowfill}}} + +\def\chemicaldoubleouterarrow + {\dochemicalouterarrow + {\lower.5\ht0\vbox + {\offinterlineskip + \hbox to \dimen2{\rightarrowfill} + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicaltwintipouterarrow + {\dochemicalouterarrow + {\hbox + {\hbox to \dimen2{\rightarrowfill}% + \hskip-\dimen2 + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space + {\chemicalspace % todo: \@@chemicaltextcolor + \chemicalinnerclip + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$% + \doresetsubscripts}% + \chemicalspace} + +\def\chemicaloutermolecule#1#2#3% + {\chemicalspace + \bgroup + \@@dochemicalcolor + \setbox0=\hbox % else the font is reset + {\dosetsubscripts + \hbox{$\@@dochemicalstyle{\strut#1}$}% + \doresetsubscripts}% + \mathop{\box0}% + \ifthirdargument + \doifnot{#2}{} + {^{\@@dochemicalstyle{\strut#2}}}% + \doifnot{#3}{} + {_{\@@dochemicalstyle{\strut#3}}}% + \else + \doifnot{#2}{} + {_{\@@dochemicalstyle{\strut#2}}}% + \fi + \egroup + \chemicalspace} + +\def\chemicalsinglepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow + {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}% + \chemicalspace$}} + +\def\chemicaldoublepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow{\overleftarrow + {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}% + \chemicalspace$}} + +% Bij de in-line bindingen wordt gebruik gemaakt van +% een \hrule. De maatvoering wordt bepaald door een +% kunstmatige em (\wd0). + +\def\somechemicalbond% + {\hrule width \wd0 height .4pt} + +\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle + {{\setbox0=\hbox + {${\@@localchemicalstyle M}$}% + \vbox to \ht0 + {\@@dochemicalcolor + \hsize\wd0 + \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}} + +\def\singlechemicalbond% + {\dochemicalbonds{}{\somechemicalbond}{}} + +\def\doublechemicalbond% + {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}} + +\def\triplechemicalbond% + {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}} + +% In plaats van \def\naam{\chemie[...]...} kan beter gebruik +% worden gemaakt van het commando +% +% \definieerchemie[naam]{commando's} +% +% De naam krijgt, om problemen met bestaande macro's te +% voorkomen, een prefix. Bij het ophalen van een commando +% worden beide definities afgehandeld. + +\def\dodefinechemical[#1]#2% + {\doifdefined{\??chemical#1} + {\writestatus{ppchtex}{chemical definition #1 is redefined}}% + \setvalue{\??chemical#1}{#2}} + +\def\definechemical% + {\dosingleargument\dodefinechemical} + +\def\getpredefinedchemical#1% + {\doifdefinedelse{\??chemical#1} + {\getvalue{\??chemical#1}} + {\doifdefinedelse{#1} + {\getvalue{#1}} + {\writestatus{ppchtex}{unknown chemical definition #1}}}} + +% Hieronder zijn de definities van de structuren opgenomen. De +% naam van de structuur is als volgt opgebouwd: +% +% \executechemicalNUMBER[#1] +% +% waarbij [#1] betrekking heeft op de tekstelementen van \chemie, +% de [tweede lijst] dus. +% +% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt +% deels door de in \execute gedefinieerde macro's afgehandeld, +% deels door algemene macro's. Segmenten hebben de vorm: +% +% [+|-|]identifier[X|XYZ|X..Y] +% +% Voorbeelden van segmenten zijn: +% +% R1 +% R1..4 +% R135 +% -R1 +% +R35 + +\setchemicalmaximum 0 + +\def\processchemical[#1]% + {\unknownchemical{#1}} + +\def\setchemicalname#1 % + {\def\chemicalname{#1}} + +\let\chemicalname=\s!unknown + +% Vooruitlopend op een gedetailleerde documentatie, zijn hier +% vast enkele gebruikte afmetingen: +% +% lengte radikalen : 500 +% afstand radikalen : 100 +% afstand dubbele radikalen : 260 +% afstand substituenten : +125 + +\def\executechemicalONE[#1]% + {\setchemicalname ONE + % + \setchemicalmaximum 8 + \setchemicaldistance 0 + \setchemicalsubstitute 625 + \setchemicaldirection 303 + % + \setchemicalrotation 1 1 0 1 0 1 0 1 0 + \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 + \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1 + \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 + \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0 + \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 + \setchemicalrotation 7 0 1 0 1 0 1 0 1 + \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 45 135 225 315 + \setchemicalangle 3 90 180 270 0 + \setchemicalangle 4 135 225 315 45 + \setchemicalangle 5 180 270 0 90 + \setchemicalangle 6 225 315 45 135 + \setchemicalangle 7 270 0 90 180 + \setchemicalangle 8 315 45 135 225 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 -1000 1000 + \setchemicaltranslate 3 0 1000 + \setchemicaltranslate 4 1000 1000 + \setchemicaltranslate 5 1000 0 + \setchemicaltranslate 6 1000 -1000 + \setchemicaltranslate 7 0 -1000 + \setchemicaltranslate 8 -1000 -1000 + % + \setchemicallinesegment SB 300 0 700 0 + \setchemicallinesegment DB1 300 50 700 50 + \setchemicallinesegment DB2 300 -50 700 -50 + % + %setchemicallinesegment EP 200 125 200 -125 + \setchemicalfactorlinesegment EP 200 125 200 -125 + % + \setchemicaltextelement ES 200 0 + \setchemicaltextelement ED1 200 50 + \setchemicaltextelement ED2 200 -50 + \setchemicaltextelement ET1 200 75 + \setchemicaltextelement ET2 200 0 + \setchemicaltextelement ET3 200 -75 + \setchemicaltextelement HB1 300 0 + \setchemicaltextelement HB2 475 0 + \setchemicaltextelement HB3 650 0 + % + \setchemicaltextelement Z 800 0 + \setchemicaltextelement RZ 950 0 + \setchemicaltextelement ZN 500 0 + \setchemicaltextelement ZTN 500 150 + \setchemicaltextelement ZBN 500 -150 + % + \def\processchemical[##1##2##3##4##5]% + {\doprocesschemical[##1##2##3##4##5] + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + DIR##4##5=>\processchemicaldirection{##4##5}, + OFF##4##5=>\processchemicaloffset{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, + LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}% + \processchemicallinesegment{DB2}{##4##5}, + RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}% + \processchemicaldashedlinesegment{DB2}{##4##5}, + OF##3:##5=>\processchemicalphantom{##3}{##5}, + OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5}, + EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5}, + ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0}, + ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0}, + ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0}, + HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5}, + SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5}, + TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}% + \processchemicallinesegment{DB}{##3##4##5}, + CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{}, + ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0}, + ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{}, + ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0}, + ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0} + {l,l,t,r,r,r,b,l}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}} + +\def\executechemicalTHREE[#1]% + {\setchemicalname THREE + % + \setchemicalmaximum 3 + \setchemicaldistance 289 + \setchemicalsubstitute 952 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 120 210 300 30 + \setchemicalangle 3 240 330 60 150 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 577 0 -289 -500 + \setchemicallinesegment SB 352 -130 -64 -370 + \setchemicallinesegment -SB 352 -130 -289 -500 + \setchemicallinesegment +SB 577 0 -64 -370 + \setchemicallinesegment DB1 327 -87 -89 -327 + \setchemicallinesegment DB2 377 -172 -39 -413 + \setchemicallinesegment R 577 0 1077 0 + \setchemicallinesegment -R 577 0 1010 250 + \setchemicallinesegment +R 577 0 1010 -250 + \setchemicallinesegment ER1 577 50 1077 50 + \setchemicallinesegment ER2 577 -50 1077 -50 + \setchemicallinesegment SR 837 0 1077 0 + \setchemicallinesegment -SR 802 130 1010 250 + \setchemicallinesegment +SR 802 -130 1010 -250 + \setchemicallinesegment DR1 837 50 1077 50 + \setchemicallinesegment DR2 837 -50 1077 -50 + % + \setchemicaltextelement Z 577 0 + \setchemicaltextelement RZ 1177 0 + \setchemicaltextelement -RZ 1097 300 + \setchemicaltextelement +RZ 1097 -300 + \setchemicaltextelement CRZ 1077 0 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3} + {l,t,r, l,r,l, r,b,l, r,l,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3} + {l,r,b, r,r,l, r,l,t, l,l,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0} + {}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3} + {l,r,r, t,r,l, r,l,l, b,l,r}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFOUR[#1]% + {\setchemicalname FOUR + % + \setchemicalmaximum 4 + \setchemicaldistance 500 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 4 0 1 1 0 0 -1 -1 0 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 180 270 0 90 + \setchemicalangle 4 270 0 90 180 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 500 500 500 -500 + \setchemicallinesegment SB 500 240 500 -240 + \setchemicallinesegment -SB 500 240 500 -500 + \setchemicallinesegment +SB 500 500 500 -240 + \setchemicallinesegment DB1 450 240 450 -240 + \setchemicallinesegment DB2 550 240 550 -240 + \setchemicallinesegment EB 360 300 360 -300 + \setchemicallinesegment R 500 500 854 854 + \setchemicallinesegment -R 500 500 500 1000 + \setchemicallinesegment +R 500 500 1000 500 + \setchemicallinesegment ER1 465 535 819 889 + \setchemicallinesegment ER2 535 465 889 819 + \setchemicallinesegment SR 684 684 854 854 + \setchemicallinesegment -SR 500 760 500 1000 + \setchemicallinesegment +SR 760 500 1000 500 + \setchemicallinesegment DR1 649 719 819 889 + \setchemicallinesegment DR2 719 649 889 819 + % + \setchemicaltextelement Z 500 500 + \setchemicaltextelement RZ 925 925 + \setchemicaltextelement -RZ 500 1100 + \setchemicaltextelement +RZ 1100 500 + \setchemicaltextelement CRZ 1038 1038 + % + \setchemicaltextelement ZN 350 350 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4} + {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4} + {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFIVE[#1]% + {\setchemicalname FIVE + % + \setchemicalmaximum 5 + \setchemicaldistance 688 + \setchemicalsubstitute 1226 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309 + \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809 + \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809 + \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 72 162 252 342 + \setchemicalangle 3 144 234 324 54 + \setchemicalangle 4 216 306 36 126 + \setchemicalangle 5 288 18 108 198 + % + \setchemicaltranslate 1 -1376 0 + \setchemicaltranslate 2 -425 1304 + \setchemicaltranslate 3 1113 809 + \setchemicaltranslate 4 1113 -809 + \setchemicaltranslate 5 -425 -1304 + % + \setchemicallinesegment A 1188 500 1188 -500 + \setchemicallinesegment B 688 500 688 -500 + \setchemicallinesegment S -263 808 688 -500 + \setchemicallinesegment SS -116 606 541 -298 + \setchemicallinesegment -SS -263 808 541 -298 + \setchemicallinesegment +SS -116 606 688 -500 + \setchemicallinesegment SB 688 240 688 -240 + \setchemicallinesegment -SB 688 240 688 -500 + \setchemicallinesegment +SB 688 500 688 -240 + \setchemicallinesegment DB1 638 240 638 -240 + \setchemicallinesegment DB2 738 240 738 -240 + \setchemicallinesegment EB 548 340 548 -340 + \setchemicallinesegment R 688 500 1093 794 + \setchemicallinesegment -R 688 500 688 1000 + \setchemicallinesegment +R 688 500 1163 345 + \setchemicallinesegment ER1 659 540 1064 834 + \setchemicallinesegment ER2 727 460 1122 754 + \setchemicallinesegment SR 898 653 1093 794 + \setchemicallinesegment -SR 688 760 688 1000 + \setchemicallinesegment +SR 935 420 1163 345 + \setchemicallinesegment DR1 869 693 1064 834 + \setchemicallinesegment DR2 927 613 1122 754 + % + \setchemicaltextelement Z 688 500 + \setchemicaltextelement RZ 1188 863 + \setchemicaltextelement -RZ 688 1100 + \setchemicaltextelement +RZ 1258 315 + \setchemicaltextelement CRZ 1323 947 + % + \setchemicalcircsegment C -36 36 590 72 475 -345 + \setchemicalcircsegment CC -72 0 590 72 182 -561 + % + \setchemicaltextelement ZN 468 350 + \setchemicaltextelement RN 860 625 % 1.25 Z + \setchemicaltextelement RTN 785 728 % .12 / 103 75 + \setchemicaltextelement RBN 935 522 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ FRONT????=>{\executechemicalFIVEFRONT[#1]}, + PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5} + {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5} + {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + -RD##4=>\processchemicaldashedlinesegment{-R}{##4}, + +RD##4=>\processchemicaldashedlinesegment{+R}{##4}, + -RB##4=>\processchemicaldeltalinesegment{-R}{##4}, + +RB##4=>\processchemicaldeltalinesegment{+R}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0}, + RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{}, + RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0}, + RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{}, + -SS##4=>\processchemicallinesegment{-SS}{##4}, + +SS##4=>\processchemicallinesegment{+SS}{##4}, + CCD##4=>\processchemicaldottsegment{CC}{##4}, + SS##3##4=>\processchemicallinesegment{SS}{##3##4}, + RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4}, + RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0}, + RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{}, + AU##3##4=>\processchemicaluparrowsegment{A}{##3##4}, + AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4}, + CC##3##4=>\processchemicalcircsegment{CC}{##3##4}, + CD##3##4=>\processchemicaldottsegment{C}{##3##4}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5} + {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + S##2##3##4=>\processchemicallinesegment{S}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIX[#1]% + {\setchemicalname SIX + % + \setchemicalmaximum 6 + \setchemicalsubstitute 1375 + \setchemicaldistance 866 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5 + \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 4 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 60 150 240 330 + \setchemicalangle 3 120 210 300 30 + \setchemicalangle 4 180 270 0 90 + \setchemicalangle 5 240 330 60 150 + \setchemicalangle 6 300 30 120 210 + % + \setchemicaltranslate 1 -1732 0 + \setchemicaltranslate 2 -866 1500 + \setchemicaltranslate 3 866 1500 + \setchemicaltranslate 4 1732 0 + \setchemicaltranslate 5 866 -1500 + \setchemicaltranslate 6 -866 -1500 + % + \setchemicallinesegment A 1386 500 1386 -500 + \setchemicallinesegment S 0 1000 866 -500 + \setchemicallinesegment SS 125 783 741 -283 + \setchemicallinesegment -SS 0 1000 741 -283 + \setchemicallinesegment +SS 125 783 866 -500 + \setchemicallinesegment B 866 500 866 -500 + \setchemicallinesegment SB 866 240 866 -240 + \setchemicallinesegment -SB 866 240 866 -500 + \setchemicallinesegment +SB 866 500 866 -240 + \setchemicallinesegment DB1 816 240 816 -240 + \setchemicallinesegment DB2 916 240 916 -240 + \setchemicallinesegment EB 726 340 726 -340 + \setchemicallinesegment R 866 500 1299 750 + \setchemicallinesegment -R 866 500 866 1000 + \setchemicallinesegment +R 866 500 1299 250 + \setchemicallinesegment ER1 841 543 1274 793 + \setchemicallinesegment ER2 891 457 1324 707 + \setchemicallinesegment SR 1091 630 1299 750 + \setchemicallinesegment -SR 866 740 866 1000 + \setchemicallinesegment +SR 1091 370 1299 250 + \setchemicallinesegment DR1 1066 673 1274 793 + \setchemicallinesegment DR2 1116 588 1324 707 + \setchemicallinesegment MID1 0 1000 -150 200 + \setchemicallinesegment MID2 0 -1000 -150 -200 + \setchemicallinesegment MIDS1 0 1000 -180 0 + \setchemicallinesegment MIDS2 0 -1000 -180 0 + % + \setchemicalcircsegment C -30 30 700 60 600 -346 + \setchemicalcircsegment CC -60 0 700 60 350 -606 + % + \setchemicaltextelement Z 866 500 + \setchemicaltextelement RZ 1386 800 + \setchemicaltextelement -RZ 866 1100 + \setchemicaltextelement +RZ 1386 200 + \setchemicaltextelement CRZ 1524 880 + \setchemicaltextelement MIDZ -150 0 + % + \setchemicaltextelement ZN 589 350 + \setchemicaltextelement RN 1083 625 % 1.25 Z + \setchemicaltextelement RTN 1008 755 % .12 / 130 75 + \setchemicaltextelement RBN 1158 495 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ FRONT????=>{\executechemicalSIXFRONT[#1]}, + MID????=>\processchemicallinesegment{MID}{1????}, + MIDS????=>\processchemicallinesegment{MIDS}{1????}, + MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{}, + PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + ROT##4##5=>\processchemicalrotation{##4##5}, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6} + {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r}, + +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6} + {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + -SR##4##5=>\processchemicallinesegment{-SR}{##4##5}, + +SR##4##5=>\processchemicallinesegment{+SR}{##4##5}, + -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5}, + +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5}, + -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5}, + +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5}, + CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{}, + -SS##4##5=>\processchemicallinesegment{-SS}{##4##5}, + +SS##4##5=>\processchemicallinesegment{+SS}{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, +RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0}, +RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{}, +RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0}, +RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{}, + SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5}, + RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5}, + RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, +RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0}, +RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{}, + AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5}, + AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5}, + CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5}, + CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5}, + ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5}, + RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6} + {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5}, + DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5}, + -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5}, + +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5}, + R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5}, + S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalSEVEN[#1]% incomplete ! + {\setchemicalname SEVEN + % + \setchemicalmaximum 7 + \setchemicalsubstitute - + \setchemicaldistance 1038 + % + \setchemicalrotation 1 .623 .782 - - - - - - + \setchemicalrotation 2 -.223 .975 - - - - - - + \setchemicalrotation 3 -.901 .434 - - - - - - + \setchemicalrotation 4 -.901 -.434 - - - - - - + \setchemicalrotation 5 -.223 -.975 - - - - - - + \setchemicalrotation 6 .623 -.782 - - - - - - + \setchemicalrotation 7 1 0 - - - - - - + % + \setchemicalangle 1 0 - - - + \setchemicalangle 2 51.429 - - - + \setchemicalangle 3 102.857 - - - + \setchemicalangle 4 154.286 - - - + \setchemicalangle 5 205.714 - - - + \setchemicalangle 6 257.143 - - - + \setchemicalangle 7 308.571 - - - + % + \setchemicaltranslate 1 - - + \setchemicaltranslate 2 - - + \setchemicaltranslate 3 - - + \setchemicaltranslate 4 - - + \setchemicaltranslate 5 - - + \setchemicaltranslate 6 - - + \setchemicaltranslate 7 - - + % + \setchemicallinesegment B 1038 500 1038 -500 + \setchemicallinesegment SB 1038 240 1038 -240 + \setchemicallinesegment -SB 1038 240 1038 -500 + \setchemicallinesegment +SB 1038 500 1038 -240 + % + \setchemicaltextelement Z 1038 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %ROT##4##5=>\processchemicalrotation{##4}, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + %ADJ##4##5=>\processchemicaldistance{##4##5}, + %MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalEIGHT[#1]% incomplete ! + {\setchemicalname EIGHT + % + \setchemicalmaximum 8 + %\setchemicalsubstitute 1307 + \setchemicaldistance 1207 + % + \setchemicalrotation 1 .707 .707 - - - - - - + \setchemicalrotation 2 0 1 - - - - - - + \setchemicalrotation 3 -.707 .707 - - - - - - + \setchemicalrotation 4 -1 0 - - - - - - + \setchemicalrotation 5 -.707 -.707 - - - - - - + \setchemicalrotation 6 0 -1 - - - - - - + \setchemicalrotation 7 .707 -.707 - - - - - - + \setchemicalrotation 8 1 0 - - - - - - + % + \setchemicalangle 1 45 - - - + \setchemicalangle 2 90 - - - + \setchemicalangle 3 135 - - - + \setchemicalangle 4 180 - - - + \setchemicalangle 5 225 - - - + \setchemicalangle 6 270 - - - + \setchemicalangle 7 315 - - - + \setchemicalangle 8 0 - - - + % + \setchemicaltranslate 1 -2414 0 + \setchemicaltranslate 2 -1706 1706 + \setchemicaltranslate 3 0 2414 + \setchemicaltranslate 4 1706 1706 + \setchemicaltranslate 5 2414 0 + \setchemicaltranslate 6 1706 -1706 + \setchemicaltranslate 7 0 -2414 + \setchemicaltranslate 8 -1706 -1706 + % + \setchemicallinesegment B 1207 500 1207 -500 + \setchemicallinesegment SB 1207 240 1207 -240 + \setchemicallinesegment -SB 1207 240 1207 -500 + \setchemicallinesegment +SB 1207 500 1207 -240 + % + \setchemicaltextelement Z 1207 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalFIVEFRONT[#1]% + {\executechemicalFIVE[]% + % + \setchemicalname FIVEFRONT + % + \setchemicallinesegment -R 688 500 688 100 + \setchemicallinesegment +R 688 500 688 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5} + {,,,,, t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5} + {,,,,, b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIXFRONT[#1]% + {\executechemicalSIX[]% + % + \setchemicalname SIXFRONT + % + \setchemicallinesegment -R 866 500 866 100 + \setchemicallinesegment +R 866 500 866 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6} + {,,,,,, t,t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6} + {,,,,,, b,b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +% 1 : 0 +% 2 : -115 +% 3* : -195 +% 3 : -165 +% 4 : -245 + +\def\executechemicalCARBON[#1]% + {\setchemicalname CARBON + % + \setchemicalmaximum 4 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423 + \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966 + \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966 + \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 115 205 295 25 + \setchemicalangle 3 165 255 345 75 + \setchemicalangle 3* 195 285 15 105 + \setchemicalangle 4 245 335 65 155 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 500 0 1000 0 + \setchemicallinesegment B2 300 0 1000 0 + \setchemicallinesegment B3 500 0 1000 0 + \setchemicallinesegment B4 300 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ MIR????=>\setchemicalmirror{3}, + -MIR????=>\resetchemicalmirror{3}, + *MIR????=>\togglechemicalmirror{3}, + CB????=>\processlocalchemicals{B,C,Z}, + C????=>\processchemicalcircsegment{C}{1????}, + -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2}, + ROT##4##5=>\processchemicalrotation{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + CB##3##4##5=>\processlocalchemicals + {ROT##3,C,B,Z2..4, + MOV##3,*MIR,-ROT##3,C,B,Z2..4}, + B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +% 1: 45 2: -90 3: -225 +% 4: -45 5: -135 6: -270 + +\newif\ifNEWMANstagger \NEWMANstaggertrue + +\def\executechemicalNEWMANSTAGGER% + {\NEWMANstaggertrue\executechemicalNEWMAN} + +\def\executechemicalNEWMANECLIPSE% + {\NEWMANstaggerfalse\executechemicalNEWMAN} + +\def\executechemicalNEWMAN[#1]% + {\setchemicalname NEWMAN + % + \setchemicalmaximum 6 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \ifNEWMANstagger + \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707 + \else + \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866 + \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259 + \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5 + \fi + \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707 + \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707 + \setchemicalrotation 6 0 1 1 0 0 -1 -1 0 + % + \ifNEWMANstagger + \setchemicalangle 1 315 45 135 225 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 225 315 45 135 + \else + \setchemicalangle 1 30 120 210 300 + \setchemicalangle 2 255 345 75 165 + \setchemicalangle 3 120 210 300 30 + \fi + \setchemicalangle 4 45 135 225 315 + \setchemicalangle 5 135 225 315 45 + \setchemicalangle 6 270 0 90 180 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 0 0 1000 0 + \setchemicallinesegment B2 0 0 1000 0 + \setchemicallinesegment B3 0 0 1000 0 + \setchemicallinesegment B4 500 0 1000 0 + \setchemicallinesegment B5 500 0 1000 0 + \setchemicallinesegment B6 500 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]}, + ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]}, + B????=>\processlocalchemicals{B1..6}, + CB????=>\processlocalchemicals{B1..6,C,Z1..6}, + C????=>\processchemicalcircsegment{C}{1????}, + ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\ifNEWMANstagger + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}% + \else + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}% + \fi, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalCHAIR[#1]% smaller + {\setchemicalname CHAIR + % + \setchemicalmaximum 6 + % + \setchemicallinesegment B1 1600 800 2800 -800 + \setchemicallinesegment B2 2800 -800 800 0 + \setchemicallinesegment B3 800 0 -1600 -800 + \setchemicallinesegment B4 -1600 -800 -2800 800 + \setchemicallinesegment B5 -2800 800 -800 0 + \setchemicallinesegment B6 -800 0 1600 800 + % + \setchemicallinesegment +R1 1600 800 1600 1600 + \setchemicallinesegment +R2 2800 -800 2800 -1600 + \setchemicallinesegment +R3 800 0 800 800 + \setchemicallinesegment +R4 -1600 -800 -1600 -1600 + \setchemicallinesegment +R5 -2800 800 -2800 1600 + \setchemicallinesegment +R6 -800 0 -800 -800 + % + \setchemicallinesegment -R1 1600 800 2350 522 % 750 278 + \setchemicallinesegment -R2 2800 -800 3493 -400 + \setchemicallinesegment -R3 800 0 1329 -600 % 528 600 + \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278 + \setchemicallinesegment -R5 -2800 800 -3493 400 + \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600 + % + \setchemicaltextelement +RZ1 1600 1800 + \setchemicaltextelement +RZ2 2800 -1800 + \setchemicaltextelement +RZ3 800 1000 + \setchemicaltextelement +RZ4 -1600 -1800 + \setchemicaltextelement +RZ5 -2800 1800 + \setchemicaltextelement +RZ6 -800 -1000 + % + \setchemicaltextelement -RZ1 2538 453 % 200 lang + \setchemicaltextelement -RZ2 3666 -300 + \setchemicaltextelement -RZ3 1460 -750 + \setchemicaltextelement -RZ4 -2538 -453 + \setchemicaltextelement -RZ5 -3666 300 + \setchemicaltextelement -RZ6 -1460 750 + % + \def\processchemical[##1##2##3##4##5]% + {\def\chemicalrotation{1}% + \processaction + [##1##2##3##4##5] + [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6}, + -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6}, + +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6}, + B##2????=>{\getchemicallinesegment[0][B##2]}, + -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]}, + +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]}, + -R##3????=>{\getchemicallinesegment[0][-R##3]}, + +R##3????=>{\getchemicallinesegment[0][+R##3]}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalarrow#1#2[#3]% + {\dogetcommalistelement1\from#3\to\toptext + \dogetcommalistelement2\from#3\to\bottext + \def\dochemicaltext##1% + {\dosetsubscripts% + $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$% + \doresetsubscripts}% + \doifelse\@@chemicallocation\v!intext + {#1{\dochemicaltext\toptext}}% + {\setbox\chemicalsymbols=\hbox + {\box\chemicalsymbols + \vbox{\halign{##\cr + \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr + #2% + \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}} + +\def\executechemicalGIVES + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {\rightarrowfill\cr}} + +\def\executechemicalEQUILIBRIUM + {\executechemicalarrow + {\chemicaldoublepicturearrow}% nodig + {\rightarrowfill\cr\leftarrowfill\cr}} + +\def\executechemicalMESOMERIC + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {$\leftarrow\hskip-1em$\rightarrowfill\cr}} + +\def\executechemicalsign#1[#2]% + {\doifelse\@@chemicallocation\v!intext + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts} + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts}}} + +\def\executechemicalPLUS + {\executechemicalsign{+}} + +\def\executechemicalMINUS + {\executechemicalsign{-}} + +\def\executechemicalEQUAL + {\executechemicalsign{=}} + +\def\executechemicalSPACE[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \quad}}} + +\def\executechemicalCHEM[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + $\@@dochemicalstyle{\@@localchemicalformat#1}$}}} + +\def\executechemicalTEXT[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols#1}}} + +%\def\executechemicalLOW[#1]% +% {\setlowsubscripts} +% +%\def\executechemicalHIGH[#1]% +% {\sethighsubscripts} + +\def\putchemicalrule#1#2#3#4% + {\ifcase\chemicaldrawingmode + \putrule from {#1} {#2} to {#3} {#4} + \or + \psline(#1,#2)(#3,#4)% + \or + \bgroup + \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + draw z1--z2 ; + \stopMPdrawing + \egroup + \fi} + +\def\executechemicalcomplex#1% + {\bgroup + \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}% + \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}% + \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}% + \egroup} + +\def\executechemicalOPENCOMPLEX[#1]% + {\executechemicalcomplex+\ignorespaces + \executechemicalSPACE[]} + +\def\executechemicalCLOSECOMPLEX[#1]% + {\executechemicalSPACE[]% + \executechemicalcomplex-\ignorespaces} + +% nog niet door midden as! + +\def\executechemicalverticalsymbol#1#2% + {\executechemicalTEXT + [$\left#1\relax + \dimen0=\@@chemicalunit + \scratchcounter=\@@chemicaltop + \advance\scratchcounter by \@@chemicalbottom + \dimen0=\scratchcounter\dimen0 + \vcenter to \dimen0{} + \dimen2=\@@chemicalunit + \dimen2=\@@chemicalright\dimen0 + \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}% + \right.$]}% + +\def\executechemicalUPARROW[#1]% + {\executechemicalverticalsymbol\uparrow{#1}} + +\def\executechemicalDOWNARROW[#1]% + {\executechemicalverticalsymbol\downarrow{#1}} + +\def\executechemicalUPDOWNARROW[#1]% + {\executechemicalverticalsymbol\updownarrow{#1}} + +\let\setchemicalattributes\relax + +\setupchemical + [\c!width=0, + \c!height=0, + \c!left=0, + \c!right=0, + \c!top=0, + \c!bottom=0, + \c!bodyfont=\the\bodyfontsize, + \c!resolution=\outputresolution, + \c!scale=\v!medium, + \c!size=\v!medium, + \c!textsize=\v!big, + \c!frame=\v!off, + \c!axis=\v!off, + \c!state=\v!start, + \c!style=\rm, + \c!location=, + \c!option=, + \c!offset=LOW, + \c!alternative=1, + \c!color=, + \c!rulethickness=, + \c!rulecolor=, + \c!factor=1] + +% Tijdelijk plaatsen we deze extra macro's hier. +% +% mathontop: \mtop {} {} +% textontop: \ttop {} {} + +\def\putontop#1#2% + {\vbox + {\halign + {\strut\hss##\hss\cr + #1\cr + #2\cr}}} + +\def\ttop#1#2% + {\putontop{\tx#1}{#2}} + +\def\mtop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\scriptscriptstyle#1$\cr + \noalign{\vskip.5ex}% + $#2$\cr}}} + +\def\ctop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr + \noalign{\vskip.5ex}% + $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}} + +%D Here are a couple of \CONTEXT\ goodies: +%D +%D \startitemize +%D \item styles hooked into \CONTEXT\ style mechanism +%D \item support for color and rulethickness (mp mode only) +%D \item position tracking +%D \stopitemize + +\ifCONTEXT \else \protect \endinput \fi + +\let\@@chemicalrulecolor\empty +\let\@@chemicalcolor \empty + +% \def\setchemicalattributes +% {\scratchdimen\@@chemicalchemicalrulethickness +% \def\chemicalattributes +% {withpen pencircle scaled \the\scratchdimen\space +% withcolor }% +% \doifelsenothing\@@chemicalchemicalrulecolor +% {\edef\chemicalattributes{\chemicalattributes black}} +% {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalchemicalrulecolor}}}% +% \startMPdrawing +% drawoptions (\chemicalattributes) ; +% \stopMPdrawing} + +\def\setchemicalattributes + {\scratchdimen\@@chemicalrulethickness + \def\chemicalattributes + {withpen pencircle scaled \the\scratchdimen\space + withcolor }% + \doifelsenothing\@@chemicalrulecolor + {\edef\chemicalattributes{\chemicalattributes black}} + {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}% + \startMPdrawing + drawoptions (\chemicalattributes) ; + \stopMPdrawing} + +\def\@@dochemicalcolor + {\doifsomething\@@chemicalcolor{\color[\@@chemicalcolor]}} + +\def\@@dochemicalstyle + {\doconvertfont\@@chemicalstyle} + +\setupchemical + [\c!rulethickness=\linewidth, + \c!rulecolor=, + \c!color=] + +\def\cpos#1#2% + {\iftrialtypesetting + #2% + \else + \bgroup + \globalpushmacro\dowithchemical + \gdef\dowithchemical##1{\hpos{#1}{##1}\globalpopmacro\dowithchemical}% + #2% + \egroup + \fi} + +\protect \endinput + +% \startchemical[axis=on,frame=yes] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=small,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=medium,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=big,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + diff --git a/tex/context/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/ppchtex.tex b/tex/context/base/ppchtex.tex deleted file mode 100644 index a7800acd4..000000000 --- a/tex/context/base/ppchtex.tex +++ /dev/null @@ -1,3438 +0,0 @@ -%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 - -% De onderstaande help-informatie (%I) kan worden opgeroepen -% in TeXEdit. De daaropvolgende setup-informatie (%S) kan -% nadat zij is uit deze file is gefilterd met TeXUtil, in -% handleidingen worden gebruikt. In deze file opgenomen -% documentatie (%D en %M) kan worden gebruikt voor een -% technische handleiding. Met %T kunnen templates worden -% gedefinieerd voor TeXEdit. - -%I n=Chemie -%I c=\stelchemiein,\chemie -%I -%I Chemische formules kunnen worden gezet met behulp van de -%I onderstaande commando's: -%I -%I buiten $ en $$ : -%I -%I \chemie[segmenten][symbolen] -%I -%I \startchemie[instellingen] -%I \chemie... -%I \chemie... -%I \stopchemie -%I -%I en binnen $ en $$: -%I -%I \chemie{}{} -%I -%I Voor tekst, uitleg en voorbeelde verwijzen we vooralsnog -%I naar de handleiding. -%P -%I Het gedrag van de macro's kan worden ingesteld met: -%I -%I \stelchemiein[breedte=,hoogte=,links=,rechts=,boven=, -%I onder=,korps=,schaal=,status=,assenstelsel=,kader=, -%I variant=,optie=,formaat=,tekstformaat=,resolutie=, -%I offset=,letter=] -%I -%I Structuren kunnen worden voorgedefinieerd met het commando -%I -%I \definieerchemie[naam]{\chemie...} - -%S \startsetup -%S \command -%S [\!stelchemiein] -%S \type -%S [\c!vars!] -%S \variable -%S [\c!breedte] -%S [\c!number!,\v!passend] -%S [0] -%S \variable -%S [\c!hoogte] -%S [\c!number!,\v!passend] -%S [0] -%S \variable -%S [\c!links] -%S [\c!number!] -%S [0] -%S \variable -%S [\c!rechts] -%S [\c!number!] -%S [0] -%S \variable -%S [\c!boven] -%S [\c!number!] -%S [0] -%S \variable -%S [\c!onder] -%S [\c!number!] -%S [0] -%S \variable -%S [\c!resolutie] -%S [\c!number!] -%S [\outputresolution] -%S \variable -%S [\c!korps] -%S [10pt,11pt,12pt] -%S [\bodyfontsize] -%S \variable -%S [\c!schaal] -%S [\v!klein,\v!middel,\v!groot] -%S [\v!middel] -%S \variable -%S [\c!formaat] -%S [\v!klein,\v!middel,\v!groot] -%S [\v!groot] -%S \variable -%S [\c!tekstformaat] -%S [\v!klein,\v!middel,\v!groot] -%S [\v!groot] -%S \variable -%S [\c!status] -%S [\v!start,\v!stop] -%S [\v!start] -%S \variable -%S [\c!kader] -%S [\v!aan,\v!uit] -%S [\v!uit] -%S \variable -%S [\c!assenstelsel] -%S [\v!aan,\v!uit] -%S [\v!uit] -%S \variable -%S [\c!optie] -%S [\v!test] -%S [] -%S \variable -%S [\c!variant] -%S [1,2] -%S [1] -%S \variable -%S [\c!offset] -%S [HIGH,LOW] -%S [LOW] -%S \variable -%S [\c!letter] -%S [\c!command!] -%S [\rm] -%S \stopsetup - -%S \startsetup -%S \command -%S [\v!startchemie] -%S \type -%S [\c!vars!\c!stp!] -%S \inheritvariable -%S [\v!stelchemiein] -%S [] -%S \stopsetup - -%S \startsetup -%S \command -%S [\v!chemie] -%S \type -%S [\c!vals!\c!vals!] -%S \value -%S [\c!list!] -%S [] -%S \value -%S [\c!list!] -%S [] -%S \stopsetup - -%S \startsetup -%S \command -%S [definieerchemie] -%S \type -%S [\c!val!\c!arg!] -%S \value -%S [\c!text!] -%S [] -%S \stopsetup - -\unprotect - -% Om te voorkomen dat sub- en superscripts botsen passen we -% wat fontdimen's aan (Knuth, The TeXBook, p179). Helaas -% kunnen deze instellingen niet lokaal worden gehouden door -% groeperen, vandaar dat een en ander moet worden geset n -% gereset. -% -% Er dient een relatie te worden gelegd met de afmetingen -% van de letters. In een eerdere versie werden daartoe de -% \fontdimen's opgehoogd. Omdat dit problemen gaf bij -% scaled fonts, is bij nader inzien gekozen voor de -% onderstaande oplossing, waarbij de nieuwe waarden worden -% afgeleid van de x-height (\fontexheight). De factor 0.70 -% is min of meer experimenteel vastgesteld. Soms worden de -% regels iets verder uit elkaar gezet. Jammer. Italic fonts -% hebben grotere cijfers en vallen min of meer uit de boot. - -\newif\ifloweredsubscripts - -% Due to some upward incompatibality of LaTeX to LaTeX2.09 -% and/or LaTeX2e we had to force \@@dochemicalstyle. Otherwise -% some weird \nullfont error comes up. - -\def\beginlatexmathmodehack - {\ifmmode - \let\endlatexmathmodehack=\relax - \else - \def\endlatexmathmodehack{$}$\@@dochemicalstyle\empty - \fi} - -\def\setsubscripts% - {\beginlatexmathmodehack - \def\dosetsubscript##1##2##3% - {\dimen0=##3\fontexheight##2% - \setxvalue{@@\string##1\string##2}{\the##1##2\relax}% - ##1##2=\dimen0\relax}% - \def\dodosetsubscript##1##2% - {\dosetsubscript{##1}{\textfont 2}{##2}% - \dosetsubscript{##1}{\scriptfont 2}{##2}% - \dosetsubscript{##1}{\scriptscriptfont2}{##2}}% - %dodosetsubscript\mathsupnormal {?}% - \dodosetsubscript\mathsubnormal {.7}% - \dodosetsubscript\mathsubcombined{.7}% - \global\loweredsubscriptstrue - \endlatexmathmodehack} - -\def\resetsubscripts - {\ifloweredsubscripts - \beginlatexmathmodehack - \def\doresetsubscript##1##2% - {\dimen0=\getvalue{@@\string##1\string##2}\relax - ##1##2=\dimen0}% - \def\dodoresetsubscript##1% - {\doresetsubscript{##1}{\textfont2}% - \doresetsubscript{##1}{\scriptfont2}% - \doresetsubscript{##1}{\scriptscriptfont2}}% - %dodoresetsubscript\mathsupnormal - \dodoresetsubscript\mathsubnormal - \dodoresetsubscript\mathsubcombined - \global\loweredsubscriptsfalse - \endlatexmathmodehack - \fi} - -\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 - \writestatus{ppchtex}{number #1 is skipped}% - \else - #3% - \fi} - {\unknownchemical{#2}}}% - -\newif\ifsmallchemicaltext - -\let\@@localchemicalstyle\empty - -\def\setupchemicalformat[#1]% - {\processaction - [\getvalue{#1\c!size}] - [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle}, - \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, - \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, - \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]% - \processaction - [\getvalue{#1\c!textsize}] - [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle}, - \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, - \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, - \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]% - \processaction - [\getvalue{#1\c!scale}] - [ \v!small=>\def\@@localchemicalscale{500}, - \v!medium=>\def\@@localchemicalscale{625}, - \v!big=>\def\@@localchemicalscale{750}, - \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]} - -\def\@@currentchemicalformat - {\ifinchemical - \@@localchemicalformat - \else - \@@localchemicalstyle - \fi} - -\def\dosetupchemical[#1]% - {\getparameters[\??chemical\s!chemical][#1]% - \doifelse{\@@chemicalchemicaloffset}{LOW} - {\setlowsubscripts} - {\sethighsubscripts}% - \setupchemicalformat[\??chemical\s!chemical]% - \ignorespaces} - -\def\setupchemical - {\dosingleargument\dosetupchemical} - -\def\@@dochemicalstyle% % default mapping - {\@@chemicalstyle} - -\def\@@dochemicalcolor% % no mapping yet - {} - -\def\@@chemicalstyle % $inner-style$ % (overloaded) - {\@@chemicalchemicalstyle} % $$outer-style$$ - -\def\@@writechemicalstate#1#2% - {} - -\def\@@beginchemicallocalpicture - {\ifcase\chemicaldrawingmode - \beginpicture - \or - \pspicture(0,0)(0,0) % is this permitted ? - \or - \pushMPdrawing - \startMPdrawing - %prologues := 1 ; - %input mp-tool ; - u := 10*\@@chemicalunit; - bboxmargin := 0pt ; - pickup pencircle scaled 2u ; % ??? - \stopMPdrawing - \beginpicture - \fi} - -\def\@@endchemicallocalpicture#1#2% - {\ifcase\chemicaldrawingmode - \endpicture - \or - \endpspicture - \or - \resetchemicalcoordinates - \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}% - \wd2=\!!zeropoint - \ht2=\!!zeropoint - \dp2=\!!zeropoint - \put {\box2} at 0 0 - \endpicture - \popMPdrawing - \fi} - -\def\@@beginchemicalpicture#1#2#3#4% - {\ifnum\chemicaldrawingmode=1 - \pspicture(#1,#3)(#2,#4)% - \def\account##1##2{}% - \psaxes[axesstyle=none,labels=none,ticks=none](#1,#3)(#2,#4)% - \else - \beginpicture - \setplotarea - x from {#1} to {#2}, - y from {#3} to {#4} - \iffixedchemical - \accountingon - \def\account##1##2% - {\put {} at {##1} {##2} }% - \else - \accountingoff - \def\account##1##2{}% - \fi - \fi - \ignorespaces} - -\def\@@endchemicalpicture% - {\ifcase\chemicaldrawingmode - \put {\box\chemicalsymbols} at 0 0 % elders - \endpicture - \or - \rput(0,0){\box\chemicalsymbols}% - \endpspicture - \or - \put {\box\chemicalsymbols} at 0 0 % elders - \ifMPdrawingdone - \resetchemicalcoordinates - \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}% - \wd2=\!!zeropoint - \ht2=\!!zeropoint - \dp2=\!!zeropoint - \put {\box2} at 0 0 % - \fi - \endpicture - \fi} - -\def\@@setchemicalcoordinatesystem#1% - {\edef\@@chemicalunit{#1}% - \ifcase\chemicaldrawingmode - \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % - \or - \psset{unit=\@@chemicalunit}% - \or - \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % - \startMPdrawing - %input mp-tool ; - %prologues := 1 ; - u := 10*#1; - bboxmargin := 0pt ; - pickup pencircle scaled 2u ; % ??? - \stopMPdrawing - \fi} - -\ifx\MPdivten\undefined % hack to prevent overflows in mp - \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} -\fi - -\def\@@setchemicalaxis#1#2#3#4% - {\ifcase\chemicaldrawingmode - \axis - bottom shiftedto y=0 - ticks from {#1} to {#2} by 500 / - \axis - left shiftedto x=0 - ticks from {#3} to {#4} by 500 / % - \or - \psaxes[labels=none,Dx=500,Dy=500](0,0)(#1,#3)(#2,#4)% - \or - \global\MPdrawingdonetrue - % we need to div beforehand because of mp limitations - \startMPdrawing - x1 := \MPdivten[#1]u ; x2 := \MPdivten[#2]u; - y1 := \MPdivten[#3]u ; y2 := \MPdivten[#4]u; - draw z1--(x2,y1)--z2--(x1,y2)--cycle ; - d := 50u ; dd := 10u ; - draw (x1,0)--(x2,0) ; - draw (0,y1)--(0,y2) ; - for i=d step -d until x1: draw (i,dd)--(i,-dd) ; endfor ; - for i=d step d until x2: draw (i,dd)--(i,-dd) ; endfor ; - for i=d step -d until y1: draw (-dd,i)--(dd,i) ; endfor ; - for i=d step d until y2: draw (-dd,i)--(dd,i) ; endfor ; - \stopMPdrawing - \fi} - -\def\@@setsecondchemicalplotsymbol% - {\ifcase\chemicaldrawingmode - \!!widtha=50.8mm - \divide\!!widtha by \@@chemicalresolution\relax - \plotsymbolspacing=\!!widtha - \setplotsymbol({\vrule\!!height\!!widtha\!!width\!!widtha})% - \fi} - -% Something for Dirk: - -\newcount \currentchemical - -%\newif \ifskipchemical - -\def\setchemicaldimensions#1#2#3% - {\bgroup - \global\advance\currentchemical by 1 - \dimen0=#1\relax - \dimen2=#2\relax - \dimen4=#3\relax - \setxvalue{chemical::\the\currentchemical}% - {\noexpand\docommand{\the\dimen0}{\the\dimen2}{\the\dimen4}}% - \egroup} - -%\def\getchemicaldimensions#1#2#3% -% {\global\advance\currentchemical by 1 -% \def\docommand##1##2##3% -% {#1=##1\relax#2=##2\relax#3=##3\relax}% -% \doifdefinedelse{chemical::\the\currentchemical} -% {\getvalue{chemical::\the\currentchemical}} -% {\docommand{6cm}{4cm}{0cm}}} -% -%\def\savechemicaldimensions% -% {\bgroup -% \writestatus{ppchtex}{saving dimensions in ppchtex.dim}% -% \def\docommand##1##2##3% -% {\immediate\write\scratchwrite -% {\noexpand\setchemicaldimensions{##1}{##2}{##3}}}% -% \immediate\openout\scratchwrite=ppchtex.dim -% \scratchcounter=0 -% \loop -% \ifnum\scratchcounter<\currentchemical -% \advance\scratchcounter by 1 -% \getvalue{chemical::\the\scratchcounter}% -% \repeat -% \immediate\closeout\scratchwrite -% \egroup} -% -%\def\loadchemicaldimensions% oh, how nice it would be to use -% {\bgroup % one of the context read commands -% \global\currentchemical=0 -% \immediate\openin\scratchread=./ppchtex.dim -% \ifeof\scratchread -% \immediate\closein\scratchread -% \global\skipchemicalfalse -% \else -% \immediate\closein\scratchread -% \input ./ppchtex.dim\relax -% \ifnum\currentchemical>0 -% \writestatus{ppchtex}{loading dimensions from ppchtex.dim}% -% \global\skipchemicaltrue -% \else -% \global\skipchemicalfalse -% \fi -% \global\currentchemical=0 -% \global\let\savechemicaldimensions=\relax -% \fi -% \egroup -% \global\let\loadchemicaldimensions=\relax} - -\ifx\normalchemicalframe\undefined - \let\normalchemicalframe\hbox % hook for educational purposes -\fi - -\unexpanded\def\complexstartchemical[#1]% - {\copyparameters - [\??chemical][\??chemical\s!chemical] - [\c!width,\c!height,\c!left,\c!right,\c!top,\c!bottom, - \c!bodyfont,\c!size,\c!scale,\c!state,\c!frame,\c!axis,\c!factor, - \c!location,\c!option,\c!alternative,\c!resolution,\c!offset,\c!style, - \c!color,\c!rulecolor,\c!rulethickness]% - \getparameters - [\??chemical] - [#1]% - % - \setupchemicalformat[\??chemical]% - % - \ifnum\chemicaldrawingmode=2 - \resetMPdrawing - \fi - % - \doif{\@@chemicalalternative}{2} - {\@@setsecondchemicalplotsymbol}% - % - \doif{\@@chemicalaxis}\v!on - {\let\chemicalframe\hbox}% - % - \!!counta=250000 - \divide\!!counta by \@@localchemicalscale - \!!widtha=\@@chemicalbodyfont - \divide\!!widtha by \!!counta - \@@setchemicalcoordinatesystem{\the\!!widtha}% - % - % \!!counta = -x \!!countc = -y - % \!!countb = +x \!!countd = +y - % - \def\calculateaxis##1##2##3##4##5% - {##1=##3\relax - ##2=##4\relax - \ifnum##5=0 - \ifnum##3=0 - \ifnum##4=0 - ##1=2000 - ##2=2000 - \fi - \fi - \else - \ifnum##3=0 - \ifnum##4=0 - ##1=##5\relax - \divide##1 by 2 - ##2=##1\relax - \else - ##1=##5\relax - \advance##1 by -##2\relax - \fi - \else - \ifnum##4=0 - ##2=##5\relax - \advance##2 by -##1\relax - \fi - \fi - \fi}% - \fixedchemicalfalse - \doif\@@chemicalwidth\v!fit - {\edef\@@chemicalwidth - {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% - \fixedchemicaltrue}% - \doif\@@chemicalheight\v!fit - {\edef\@@chemicalheight - {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% - \fixedchemicaltrue}% - \doifelse\@@chemicallocation\v!intext - {\!!counta=0 \!!countb=0 - \!!counta=0 \!!countd=0 } - {\calculateaxis - \!!counta\!!countb - \@@chemicalleft\@@chemicalright\@@chemicalwidth - \calculateaxis - \!!countc\!!countd - \@@chemicalbottom\@@chemicaltop\@@chemicalheight}% - % - \edef\@@chemheight {\the\!!countc}% - \edef\@@chemdepth {\the\!!countd}% - \edef\@@chemicaltop {\the\!!countc}% - \edef\@@chemicalbottom{\the\!!countd}% - % - \doifinsetelse\v!on{\@@chemicalframe,\@@chemicalaxis} - {\def\@@chemicalborder{\chemicalframe}} - {\def\@@chemicalborder{\normalchemicalframe}}% - % - \setbox0=\hbox\bgroup % this was a \vbox which took \hsize - % - \@@beginchemicalpicture - {-\the\!!counta}{\the\!!countb} - {-\the\!!countc}{\the\!!countd}% - \doif{\@@chemicalstate}\v!start - {\doif\@@chemicalaxis\v!on - {\@@setchemicalaxis - {-\the\!!counta}{\the\!!countb} - {-\the\!!countc}{\the\!!countd}}}% - \doifelse\@@chemicaloption\v!test - {\def\@@writechemicalstate##1##2% - {\convertargument##2\to\ascii - \writestatus{##1}{\ascii}}} - {\def\@@writechemicalstate##1##2{}}% - \ignorespaces} - -\def\dostartchemical% - {\catcode`\^=\@@superscript% t.b.v. \enableduplication - \catcode`\_=\@@subscript % t.b.v. de zekerheid - \begingroup - \inchemicaltrue - \def\toptext##1{\gdef\thetoptext{##1}\ignorespaces}\toptext{}% - \def\bottext##1{\gdef\thebottext{##1}\ignorespaces}\bottext{}% - \def\midtext##1{\gdef\themidtext{##1}\ignorespaces}\midtext{}% - \def\@@chemicalpostponed{}% - \complexorsimpleempty\startchemical} - -\def\startchemical - {\bgroup % t.b.v. ungrouped floats -% \loadchemicaldimensions -% \ifskipchemical -% \def\dostartchemical% -% {\def\dummy[####1]{}\dosingleempty\dummy}% -% \def\chemical% -% {\def\dummy[####1][####2][####3]{}\dotripleempty\dummy}% -% \def\toptext##1{}% -% \def\midtext##1{}% -% \def\bottext##1{}% -% \fi - \dostartchemical} - -\def\stopchemical - {%\ifskipchemical - % \getchemicaldimensions{\dimen0}{\dimen2}{\dimen4}% - % \dimen8=\dimen2\advance\dimen8 by \dimen4 - % \setbox0=\vbox to \dimen8 - % {\vss\hbox to \dimen0{\hss\the\currentchemical\hss}\vss}% - % \wd0=\dimen0\ht0=\dimen2\dp0=\dimen4 - % \chemicalframe{\box0}% - %\else - \checkchemicalpicture - \@@endchemicalpicture - \egroup - \ifnum\chemicaldrawingmode=1 - \dimen0=\@@chemicalunit - \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}% - \ht0=\@@chemheight\dimen0 - \dp0=\@@chemdepth\dimen0 - \fi - \dimen0=\ht0 - \advance\dimen0 by \dp0 - \inchemicalfalse % enables \chemie{} in text - \setbox4=\alignedchemical\themidtext - \setbox6=\alignedchemical\thetoptext - \setbox8=\alignedchemical\thebottext - \setbox4=\hbox to \wd0 - {\strut\hss$\vcenter{\box4}$\hss}% - \setbox2=\vbox to \dimen0 - {\hbox to \wd0{\strut\hss\box6\hss} - \vfill - \hbox to \wd0{\strut\hss\box8\hss} - \vss}% disables the depth - \wd0=0pt \wd4=0pt - \ht2=\ht0 \dp2=\dp0 - \ht4=\ht0 \dp4=\dp0 - %\setchemicaldimensions{\wd2}{\ht2}{\dp2}% - \@@chemicalborder{\box0\box4\box2}% text on top of chemicals - \endgroup - %\fi - \ignorespaces - \egroup} % t.b.v. ungrouped floats - -\def\alignedchemical#1% - {\vtop - {\def\par{\egroup\hbox\bgroup\strut}% - \let\\=\par - \let\endgraf=\par - \hbox\bgroup\strut#1\egroup}} - -% \setchemicalcoordinates{#1}{#2} -% -% #1: verplaatsing in x-richting -% #2: verplaatsing in y-richting - -\newif\ifchemicaldirection - -\def\checkchemicaldirection#1#2% - {\ifchemicaldirection - \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi - \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi - \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi - \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi - \chemicaldirectionfalse - \fi} - -\def\processchemicaldirection% - {\chemicaldirectiontrue\processchemicaltranslate} - -\def\setchemicalcoordinates#1#2% - {\advance\horchemical #1\relax - \advance\verchemical #2\relax - \checkchemicaldirection{#1}{#2}% - \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}% - \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}% - \ifnum\chemicaldrawingmode=1 - % njet - \else - \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} - \fi} - -\def\resetchemicalcoordinates - {\horchemical=0 - \verchemical=0 - \edef\chemicalxoffset{0}% - \edef\chemicalyoffset{0}% - \ifnum\chemicaldrawingmode=1 - % njet - \else - \setcoordinatesystem point at 0 0 - \fi} - -\def\restorechemicalcoordinates - {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}% - \edef\chemicalxoffset{\the\horchemical}% - \edef\chemicalyoffset{\the\verchemical}% - \ifnum\chemicaldrawingmode=1 - % njet - \else - \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} - \fi} - -\def\setchemicaltranslate #1 #2 #3 - {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}} - -\def\processchemicaltranslate#1% - {\def\doprocess[##1##2]% - {\doifchemicalnumber{##1}{MOV#1} - {\ifnum##1=0 - \def\chemicaloffset{0}% incompatible change - \resetchemicalcoordinates - \else - \getvalue{\s!translate##1}% - \dochemicaloffset{##1}% - \def\chemicaloffset{0}% - \fi}}% - \doprocess[#1]} - -\def\setchemicaldistance #1 - {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}% - \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}% - \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}% - \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}} - -\def\setchemicaldirection #1 - {\def\chemicaldirection{#1}} - -\def\processchemicaldistance#1% - {\def\doprocess[##1##2]% - {\doifchemicalnumber{##1}{ADJ#1} - {\ifnum##1=0 - \resetchemicalcoordinates - \else - \def\@@chemicalpostponed{\getvalue{\s!distance##1}}% - \@@chemicalpostponed - \fi}}% - \doprocess[#1]} - -\def\setchemicalsubstitute #1 - {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}% - \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}% - \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}% - \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}} - -\def\processchemicalsubstitute#1% - {\def\doprocess[##1##2]% - {\doifchemicalnumber{##1}{SUB#1} - {\ifnum##1=0 - \resetchemicalcoordinates - \else - \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}% - \@@chemicalpostponed - \fi}}% - \doprocess[#1]} - -% Het is mogelijk een offset of move meerdere malen uit te -% voeren, door een nummer voor het commando te plaatsen. - -\def\chemicalrepeat {1} - -\def\redoprocesschemical[#1#2]% - {\doifinstringelse{#1}{0123456789.} - {\edef\chemicalrepeat{\chemicalrepeat#1}% - \redoprocesschemical[#2]} - {\processchemical[#1#2]% - \def\chemicalrepeat{1}}} - -\def\doprocesschemical[#1#2]#3% - {\doifinstringelse{#1}{0123456789.} - {\def\chemicalrepeat{#1}% - \redoprocesschemical[#2]} - {#3}} - -% \dochemicaloffset{#1} -% -% #1: binding - -\def\chemicaloffset{0} - -\def\processchemicaloffset#1% - {\dimen0=62500 sp % real calc on cardinals, funny number - \dimen0=\chemicalrepeat\dimen0 - \divide\dimen0 by \@@localchemicalscale - \!!counta=\dimen0 - \def\doprocess[##1##2]% - {\doifinstringelse{##1}{128} - {\edef\chemicaloffset{\the\!!counta}} - {\doifinstringelse{##1}{456} - {\edef\chemicaloffset{-\the\!!counta}} - {\doifelse{##1}{0} - {\edef\chemicaloffset{0}} - {\unknownchemical{OFF#1}}}}}% - \doprocess[#1]} - -\def\dochemicaloffset#1% - {\ifnum\chemicaloffset=0 - \def\undochemicaloffset{}% - \else - \setchemicalcoordinates{-\chemicaloffset}{0}% - \def\undochemicaloffset% - {\setchemicalcoordinates{\chemicaloffset}{0}% - \def\undochemicaloffset{}}% - \fi} - -\def\processchemicalphantom#1#2% - {\setbox0=\hbox - {\def\splitoff##1????{##1}% - $\@@dochemicalstyle{\@@localchemicalformat\splitoff#2}$}% - \dimen0=.25\wd0 - \divide\dimen0 by \@@localchemicalscale - \!!counta=\dimen0 - \doifinstringelse{#1}{128} - {\edef\chemicaloffset{\the\!!counta}} - {\doifinstringelse{#1}{456} - {\edef\chemicaloffset{-\the\!!counta}} - {\doifelse{#1}{0} - {\edef\chemicaloffset{0}} - {\unknownchemical{OF#1:#2}}}}} - -% \dosetchemicalrotation{#1}{#2} -% -% #1: cos(phi) -% #2: sin(phi) - -\def\chemicalrotation {1} -\def\chemicalangle {0} -\def\chemicalxoffset {0} -\def\chemicalyoffset {0} - -\def\setchemicalmirror#1% - {\setvalue{\s!mirror#1}{*}} - -\def\resetchemicalmirror#1% - {\resetvalue{\s!mirror#1}} - -\def\togglechemicalmirror#1% - {\doifelse{\getvalue{\s!mirror#1}}{*} - {\resetchemicalmirror{#1}} - {\setchemicalmirror{#1}}} - -\def\setchemicalrotation #1 #2 #3 #4 #5 #6 #7 #8 #9 - {\setvalue{\s!rotate1.#1}{\dosetchemicalrotation{#2}{#3}}% - \setvalue{\s!rotate2.#1}{\dosetchemicalrotation{#4}{#5}}% - \setvalue{\s!rotate3.#1}{\dosetchemicalrotation{#6}{#7}}% - \setvalue{\s!rotate4.#1}{\dosetchemicalrotation{#8}{#9}}} - -\def\setchemicalangle #1 #2 #3 #4 #5 - {\setvalue{\s!angle1.#1}{\dosetchemicalangle{#2}}% - \setvalue{\s!angle2.#1}{\dosetchemicalangle{#3}}% - \setvalue{\s!angle3.#1}{\dosetchemicalangle{#4}}% - \setvalue{\s!angle4.#1}{\dosetchemicalangle{#5}}} - -\def\chemicalrotate[#1]% - {\doifdefinedelse{\s!mirror#1} - {\getvalue{\s!rotate\chemicalrotation.#1\getvalue{\s!mirror#1}}% - \getvalue{\s!angle\chemicalrotation.#1\getvalue{\s!mirror#1}}} - {\getvalue{\s!rotate\chemicalrotation.#1}% - \getvalue{\s!angle\chemicalrotation.#1}}} - -\def\dosetchemicalangle#1% zwak zie onder - {\def\chemicalangle{#1}} - -\def\dosetchemicalrotation#1#2% - {\ifnum\chemicaldrawingmode=1 - % njet - \else - \startrotation by {#1} {#2} %% \stoprotation (t.b.v. testen) - \fi} - -\def\doresetchemicalrotation - {\ifnum\chemicaldrawingmode=1 - % njet - \else - \stoprotation - \fi} - -\def\processchemicalrotation#1% - {\def\doprocess[##1##2]% - {\doifnumberelse{##1} - {\def\chemicalrotation{##1}} - {\unknownchemical{ROT#1}}}% - \doprocess[#1]} - -% \filtertextelement[#1][#2][#3][#4] -% -% #1: volgnummer -% #2: offset in uitlijningen -% #3: lijst met uitlijningen -> \chemicalloca -% #4: lijst met teksten -> \chemicaltext - -\def\setchemicallocation#1% - {\doifelse{#1}{} - {\edef\chemicalloca{c}} - {\edef\chemicalloca{#1}}} - -\newif\iffixedchemicaltext - -\def\filterchemicaltextelement[#1][#2][#3][#4]% - {\ifchemicaltextconstant - \def\chemicaltext{#4}% - \setchemicallocation{}% - \else - \ifnum#1=0\relax - \setchemicallocation{}% - \else - \iffixedchemicaltext - \!!counta#2 - \else - \!!counta=\chemicalrotation - \advance\!!counta -1 - \multiply\!!counta #2 - \advance\!!counta #1 - \fi - \getfromcommalist[#3][\the\!!counta]% - \setchemicallocation\commalistelement - \fi - \ifchemicalpicture - \let\chemicaltext\relax - \else - \advance\txtchemical 1 - \getfromcommalist[#4][\txtchemical]% - \let\chemicaltext\commalistelement - \fi - \fi - \fixedchemicaltextfalse} - -% \putchemicaltext{#1}{#2} -% -% #1 : x-coordinaat -% #2 : y-coordinaat -% -% \chemicaltext en \chemicalloca worden met \gettextelement -% opgehaald uit de tweede set bij \chemie -% -% Ten behoeve van testdoeleinden wordt gebruik gemaakt van -% \chemicalframe in plaats van het meer sjieke, maar tevens -% meer trage \framed. - -\ifx\ruledhbox\undefined - \def\chemicalframe#1% - {\hbox - {\vrule\hskip-.4pt - \vbox{\hrule\vskip-.4pt\hbox{#1}\vskip-.4pt\hrule}% - \hskip-.4pt\vrule}} -\else - \def\chemicalframe#1% - {\ruledhbox{#1}} -\fi - -\def\doputchemicaltext#1 [#2] at #3 #4 % - {\ifnum\chemicaldrawingmode=1 - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\expanded{\rput[#2]{\chemicalangle}(#3,#4){#1}}}% - \else - \put {#1} [#2] at {#3} {#4} % - \fi} - -\def\dodoifsinglelocation#1#2\\#3% - {\ifx#2\relax#3\fi} - -\def\doifsinglelocationelse#1% - {\expandafter\dodoifsinglelocationelse#1\relax\\} - -\def\putchemicaltext#1#2% - {\enablechemicalspecials - \ifchemicalpicture - \setchemicalpicture{#1}{#2}% - \else - \doifelse\@@chemicaloption\v!test - {\def\@@chemicalframe{\chemicalframe}} - {\def\@@chemicalframe{}}% - \dosetsubscripts - \setbox2=\hbox{$\@@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}}% - \ifdim\wd2>\wd6 - \doifelse{#1}{0} - {\doifnot{#2}{0}{\wd2=\wd6}} - {%\doifsinglelocation\chemicalloca - {\doifinset{\chemicalloca}{t,b}{\wd2=\wd6}}}% common ? - \fi - \expanded - {\doputchemicaltext - {\noexpand\dowithchemical{\copy2}} % per se \copy2 i.p.v. \box2 - [\chemicalloca] at {#1} {#2} } - \nomoreaccounting - \fi - \disablechemicalspecials} - -\def\setchemicaltextelement #1 #2 #3 - {\setvalue{\s!chemicaltextelement#1}{\putchemicaltext{#2}{#3}}} - -\def\getchemicalfixedtextelement% - {\fixedchemicaltexttrue - \getchemicaltextelement} - -\def\getchemicaltextelement[#1][#2][#3][#4][#5]% - {\filterchemicaltextelement[#2][#3][#4][#5]% - \doifelse{#2}{0} - {\dochemicaloffset{#2}% % incompatible change - \putchemicaltext{0}{0}% - \undochemicaloffset} % incompatible change - {\chemicalrotate[#2]% - \dochemicaloffset{#2}% - \def\chemicaltextelementnumber{#2}% - \getvalue{\s!chemicaltextelement#1}% - \getvalue{\s!chemicaltextelement#11}% - \getvalue{\s!chemicaltextelement#12}% - \getvalue{\s!chemicaltextelement#13}% - \undochemicaloffset}} - -\def\processchemicaltextelement#1#2#3#4#5% - {\def\doprocess[##1##2##3##4##5]% - {\doifelse{##1}{?} - {\doprocess[1..\maxchemical ????]} - {\doifchemicalnumber{##1}{#1#2} - {\doifelse{##2##3}{..} - {\doifchemicalnumber{##4}{#1#2} - {\getchemicaltextelement[#1][##1][#4][#5][#3]% - \doifnot{##1}{##4} - {\!!counta=##1\relax - \advance\!!counta by 1 - \edef\nextsegment{\the\!!counta}% - \doprocess[\nextsegment..##4##5]}}} - {\getchemicaltextelement[#1][##1][#4][#5][#3]% - \doifnot{##2}{?}{\doprocess[##2##3##4##5]}}}}}% - \doprocess[#2]% - \smallchemicaltextfalse} - -\def\processchemicalsmalltextelement% - {\smallchemicaltexttrue\processchemicaltextelement} - -\def\processchemicalsmalltextconstant% - {\smallchemicaltexttrue\processchemicaltextconstant} - -\def\processchemicalunrotatedtextelement#1#2#3#4#5#6% - {\bgroup - \xdef\@@xxx{0}% - \xdef\@@yyy{0}% - \def\putchemicaltext##1##2% - {\xdef\@@xxx{##1}% - \xdef\@@yyy{##2}}% - \getvalue{\s!chemicaltextelement#1}% - \egroup - \bgroup - \def\doputchemicaltext##1 [##2] at ##3 ##4 % - {\ifnum\chemicaldrawingmode=1 - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\rput{\chemicalangle}(\@@xxx,\@@yyy){\expanded{\rput[##2](##3,##4){##1}}}}% - \else - \put - {\stoprotation \setcoordinatesystem point at 0 0 - \expanded{\put {##1} [##2] at {##3} {##4} }} - at {\@@xxx} {\@@yyy} - \fi}% - \processchemicaltextelement{#2}{#3}{#4}{#5}{#6}% - \egroup} - -\newif\ifchemicaltextconstant - -\def\processchemicaltextconstant#1#2#3#4% - {\chemicaltextconstanttrue - \let\@@oldchemicalframe\@@chemicalframe - \let\@@chemicalframe\relax - \processchemicaltextelement{#1}{#2}{#3}{#4}{}% - \let\@@chemicalframe\@@oldchemicalframe - \chemicaltextconstantfalse} - -% \plotchemicalline{#1}{#2}{#3}{#4} -% -% #1: x-coordinaat beginpunt -% #2: y-coordinaat beginpunt -% #3: x-coordinaat eindpunt -% #4: y-coordinaat eindpunt - -\chardef\chemicallinetype=0 - -\def\doplotchemicalline - {\!!counte=\!!countc \advance\!!counte by -\!!counta - \!!countf=\!!countd \advance\!!countf by -\!!countb - \bgroup - \ifcase\chemicaldrawingmode - \ifcase\chemicallinetype - % 0 : normal line - \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% - \or - % 1 : normal arrow - \arrow <5pt> [.2,.67] from {\!!counta} {\!!countb} to {\!!countc} {\!!countd} - \or - % 2 : reverse arrow - \arrow <5pt> [.2,.67] from {\!!countc} {\!!countd} to {\!!counta} {\!!countb} - \or - % 3 : unrotated line - \put {\stoprotation \setcoordinatesystem point at 0 0 - \plot 0 0 {\!!counte} {\!!countf} /} - [\chemicallineposition] at {\!!counta} {\!!countb} - \else - % 4 : dashed line - \findlength {\plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /}% - \setdashesnear <2pt> for <\totalarclength>% - \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% - \fi - \or - \ifcase\chemicallinetype - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% - \or - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psline{->}(\!!counta,\!!countb)(\!!countc,\!!countd)}% - \or - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psline{<-}(\!!counta,\!!countb)(\!!countc,\!!countd)}% - \or - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\expanded{\rput[\chemicallineposition]{-\chemicalangle}% - (\!!counta,\!!countb){\psline(0,0)(\!!counte,\!!countf)}}}% - \else - \psset{linestyle=dashed}% - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% - \fi - \or - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - x0 := \MPdivten[\chemicalxoffset]u ; - y0 := \MPdivten[\chemicalyoffset]u ; - x1 := \MPdivten[\the\!!counta]u ; - y1 := \MPdivten[\the\!!countb]u ; - x2 := \MPdivten[\the\!!countc]u ; - y2 := \MPdivten[\the\!!countd]u ; - x3 := \MPdivten[\the\!!counte]u ; - y3 := \MPdivten[\the\!!countf]u ; - \ifcase\chemicallinetype - % 0 : normal line - draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \or - % 1 : normal arrow - drawarrow ((z1--z2) rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \or - % 2 : reverse arrow - drawarrow ((z2--z1) rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \or - % 3 : unrotated line % nog \chemicalineposition: t/b - draw (origin--z3) - shifted (z1 rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \else - % 4 : dashed line - draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) -% shifted z0 dashed evenly ; - shifted z0 dashed dashpattern(on 5.5u off 6u) ; - \fi - \stopMPdrawing - \fi - \egroup - \account\!!counta\!!countb - \account\!!countc\!!countd} - -\def\plotchemicalline#1#2#3#4% - {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax - \doplotchemicalline} - -\def\plotchemicalfactorline#1#2#3#4% - {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax - \ifdim\@@chemicalfactor\onepoint=\onepoint \else - \scratchdimen\!!counta\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!counta\scratchdimen - \scratchdimen\!!countc\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!countc\scratchdimen - \fi - \doplotchemicalline} - -\def\plotchemicalzline#1#2#3#4% - {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax - \ifnum\chemicaldrawingmode=2 - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - x0 := \MPdivten[\chemicalxoffset]u ; - y0 := \MPdivten[\chemicalyoffset]u ; - x1 := \MPdivten[\the\!!counta]u ; - y1 := \MPdivten[\the\!!countb]u ; - x2 := \MPdivten[\the\!!countc]u ; - y2 := \MPdivten[\the\!!countd]u ; - filldraw (( - \ifnum\chemicalangle>180 - z1--z2 - \else\ifnum\chemicalangle<90 - z1--(z2 shifted (-2u,+2u))--(z2 shifted (+2u,-2u)) - \else\ifnum\chemicalangle=90 - (z1 shifted (-2u,+2u))--(z1 shifted (+2u,-2u))-- - (z2 shifted (+2u,+2u))--(z2 shifted (-2u,-2u)) - \else - (z1 shifted (+2u,+2u))--(z1 shifted (-2u,-2u))--z2 - \fi\fi\fi - --cycle) rotatedaround(origin,-\chemicalangle)) shifted z0 ; - \stopMPdrawing - \else - \doplotchemicalline - \ifnum\chemicalangle>180 \else - \ifnum\chemicalangle=90 - \advance\!!counta by -20 \advance\!!countc by -20 - \doplotchemicalline - \advance\!!counta by 40 \advance\!!countc by 40 - \else\ifnum\chemicalangle<90 - \advance\!!countc by -20 \advance\!!countd by +20 - \doplotchemicalline - \advance\!!countc by +40 \advance\!!countd by -40 - \else - \advance\!!counta by 20 \advance\!!countb by 20 - \doplotchemicalline - \advance\!!counta by -40 \advance\!!countb by -40 - \fi\fi - \fi - \doplotchemicalline - \fi} - -\def\plotchemicaldeltaline#1#2#3#4% - {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax - \ifnum\chemicaldrawingmode=2 - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - x0 := \MPdivten[\chemicalxoffset]u ; - y0 := \MPdivten[\chemicalyoffset]u ; - x1 := \MPdivten[\the\!!counta]u ; - y1 := \MPdivten[\the\!!countb]u ; - x2 := \MPdivten[\the\!!countc]u ; - y2 := \MPdivten[\the\!!countd]u ; - filldraw ((z1--(z2 rotatedaround(z1,5))--(z2 rotatedaround(z1,-5)) - --cycle) rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \stopMPdrawing - \account{#1}{#2}% - \account{#3}{#4}% - \else - \doplotchemicalline - \advance\!!countc by 16 \advance\!!countd by -21 - \doplotchemicalline - \advance\!!countc by -4 \advance\!!countd by 7 - \doplotchemicalline - \advance\!!countc by -4 \advance\!!countd by 7 - \doplotchemicalline - \advance\!!countc by -8 \advance\!!countd by 14 - \doplotchemicalline - \advance\!!countc by -4 \advance\!!countd by 7 - \doplotchemicalline - \advance\!!countc by -4 \advance\!!countd by 7 - \doplotchemicalline - \advance\!!countc by -4 \advance\!!countd by 7 - \doplotchemicalline - \fi} - -\def\setchemicallinesegment #1 #2 #3 #4 #5 - {\setvalue{\s!chemicallinesegment#1}{\plotchemicalline{#2}{#3}{#4}{#5}}} - -\def\setchemicalfactorlinesegment #1 #2 #3 #4 #5 - {\setvalue{\s!chemicallinesegment#1}{\plotchemicalfactorline{#2}{#3}{#4}{#5}}} - -\def\getchemicallinesegment[#1][#2]% - {\chemicalrotate[#1]% - \dochemicaloffset{#1}% - \getvalue{\s!chemicallinesegment#2}% - \getvalue{\s!chemicallinesegment#21}% - \getvalue{\s!chemicallinesegment#22}% - \undochemicaloffset} - - -\def\getprivatechemicallinesegment[#1][#2]% - {\chemicalrotate[#1]% - \getvalue{\s!chemicallinesegment#2#1}} - -\def\doprocesschemicallinesegment#1#2#3#4#5% - {\chardef\chemicallinetype=#1 - \def\chemicallineposition{#2}% - \def\doprocess[##1##2##3##4##5]% - {\doifelse{##1}{?} - {\doprocess[1..\maxchemical ????]} - {\doifchemicalnumber{##1}{#4#5} - {\doifelse{##2##3}{..} - {\doifchemicalnumber{##4}{#4#5} - {#3[##1][#4]% - \doifnot{##1}{##4} - {\!!counta=##1\relax - \advance\!!counta by 1 - \edef\nextsegment{\the\!!counta}% - \doprocess[\nextsegment..##4##5]}}} - {#3[##1][#4]% - \doifnot{##2}{?} - {\doprocess[##2##3##4##5]}}}}}% - \doprocess[#5]} - -\def\processchemicallinesegment - {\doprocesschemicallinesegment0c\getchemicallinesegment} - -\def\processchemicalzlinesegment#1#2% - {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% - \bgroup - \def\plotchemicalline{\plotchemicalzline}% - \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% - \egroup} - -\def\processchemicaldeltalinesegment#1#2% - {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% - \bgroup - \def\plotchemicalline{\plotchemicaldeltaline}% - \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% - \egroup} - -\def\processprivatechemicallinesegment% - {\doprocesschemicallinesegment0c\getprivatechemicallinesegment} - -\def\processchemicaldownarrowsegment% - {\doprocesschemicallinesegment1c\getchemicallinesegment} - -\def\processchemicaluparrowsegment% - {\doprocesschemicallinesegment2c\getchemicallinesegment} - -\def\processchemicalunrotatedlinesegment#1% - {\doprocesschemicallinesegment3{#1}\getchemicallinesegment} - -\def\processchemicaldashedlinesegment% - {\doprocesschemicallinesegment4c\getchemicallinesegment} - -\def\processchemicalopenend#1#2% - {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}} - -\def\doprocesschemicalopenend[#1][#2]% - {\chemicalrotate[#1]% - \dochemicaloffset{#1}% - \ifcase\chemicaldrawingmode - \beginpicture - \setquadratic\plot - 300 0 400 0 - 500 0 550 75 - 600 0 650 -75 - 700 0 750 75 - 800 0 850 -75 - 900 0 950 0 - 1050 0 / - \endpicture - \or - \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psline(300,0)(500,0)% - \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}% - \psline(950,0)(1050,0)}% - \or - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - x0 := \MPdivten[\chemicalxoffset]u ; - y0 := \MPdivten[\chemicalyoffset]u ; - draw - (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u).. - (60.0u,0)..(65.0u,-7.5u)..(70.0u,0).. - (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up} - (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle)) - shifted z0 ; - \stopMPdrawing - \fi - \undochemicaloffset} - -% \plotchemicalcircle{#1}{#2}{#3}{#4} -% -% #1: lengte van de boog in graden -% #2: x-coordinaat eindpunt -% #3: y-coordinaat eindpunt - -\newif\ifchemicaldotted - -\def\plotchemicalcircle#1#2#3#4#5#6% - {\bgroup - \ifcase\chemicaldrawingmode - \ifchemicaldotted - \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }% - \divide\totalarclength by 6 - \def\b{\the\totalarclength}% - \divide\totalarclength by 2 - \def\a{\the\totalarclength}% - \setdashpattern <\a,\b,\b,\b,\b,\b,\a> - \fi - \circulararc {#4} degrees from {#5} {#6} center at {0} {0} % - \or - \ifchemicaldotted - \psset{linestyle=dashed}% - \fi - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\psarc(0,0){#3}{#1}{#2}}% - \or - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - r := \MPdivten[#3]*2u; - x0 := \MPdivten[\chemicalxoffset]u ; - y0 := \MPdivten[\chemicalyoffset]u ; - draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r))) - rotatedaround (origin,\chemicalangle+150)) - shifted z0 \ifchemicaldotted dashed withdots \fi ; - \stopMPdrawing - \fi - \egroup} - -\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7 - {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}} - -\def\getchemicalcircsegment[#1][#2]% - {\chemicalrotate[#1]% - \getvalue{\s!chemicalcircsegment#2}} - -\def\doprocesschemicalcircsegment#1#2% - {\def\doprocess[##1##2##3##4##5]% - {\doifelse{##1}{?} - {\doprocess[1..\maxchemical ????]} - {\doifchemicalnumber{##1}{#1#2} - {\doifelse{##2##3}{..} - {\doifchemicalnumber{##4}{#1#2} - {\getchemicalcircsegment[##1][#1]% - \doifnot{##1}{##4} - {\!!counta=##1\relax - \advance\!!counta by 1 - \edef\nextsegment{\the\!!counta}% - \doprocess[\nextsegment..##4##5]}}} - {\getchemicalcircsegment[##1][#1]% - \doifnot{##2}{?} - {\doprocess[##2##3##4##5]}}}}}% - \doprocess[#2]} - -\def\processchemicalcircsegment% - {\chemicaldottedfalse\doprocesschemicalcircsegment} - -\def\processchemicaldottsegment% - {\chemicaldottedtrue\doprocesschemicalcircsegment} - -\let\endchemicalpicture = \relax -\let\checkchemicalpicture = \relax -\let\nomoreaccounting = \relax - -\newif\ifchemicalpicture - -\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET - {\checkchemicalpicture - \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT - \chemicalpicturetrue - \processchemical[#1]} - -\def\setchemicalpicture#1#2% - {\chemicalpicturefalse - \def\endchemicalpicture% - {\@@endchemicallocalpicture{#1}{#2}% - \egroup - \ifnum\chemicaldrawingmode=1 - \rput - {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% - {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}% - \else - \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} } - \fi - \egroup}% - \def\checkchemicalpicture% - {\ifx\endchemicalpicture\relax \else - \writestatus{ppchtex}{missing end of picture (PE)}% - \endchemicalpicture - \fi}% - \setbox\nextbox=\hbox\bgroup - \@@beginchemicallocalpicture - % alternatief: gewoon accounting, en zelf l,r afhandelen - \ifnum\chemicaldrawingmode=1 - % njet - \else - \accountingon - \let\nomoreaccounting=\accountingoff - \fi} - -\def\doskipchemical[#1][#2]% - {{\tt[ppchtex]}} - -\def\skipchemical% - {\dodoubleargument\doskipchemical} - -\def\complexchemical% met \expandafter - {\ifinchemical - \expandafter\dochemical - \else - \writestatus{ppchtex}{the [][]-alternative is not permitted here}% - \expandafter\skipchemical - \fi} - -\newif\ifinnerchemical - -\def\dosimplechemical#1#2#3% - {\doifdefinedelse{\??chemical\c!location} - {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}} - {\ifinnerchemical - \let\chemicalsign = \chemicalinnersign - \let\chemicalmolecule = \chemicalinnermolecule - \let\chemicalsinglearrow = \chemicalsingleinnerarrow - \let\chemicaldoublearrow = \chemicaldoubleinnerarrow - \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow - \else - \let\chemicalsign = \chemicaloutersign - \let\chemicalmolecule = \chemicaloutermolecule - \let\chemicalsinglearrow = \chemicalsingleouterarrow - \let\chemicaldoublearrow = \chemicaldoubleouterarrow - \let\chemicaltwintiparrow = \chemicaltwintipouterarrow - \fi - \disablechemicalspecials - \unexpandedprocessallactionsinset - [#1] - [ HIGH=>\sethighsubscripts, - LOW=>\setlowsubscripts, - PLUS=>\chemicalsign{+}, - GIVES=>\chemicalsinglearrow{#2}{#3}, - EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3}, - MESOMERIC=>\chemicaltwintiparrow{#2}{#3}, - SINGLE=>\singlechemicalbond, - DOUBLE=>\doublechemicalbond, - TRIPLE=>\triplechemicalbond, - +=>\chemicalsign{+}, - ->=>\chemicalsinglearrow{#2}{#3}, - <->=>\chemicaldoublearrow{#2}{#3}, - <>=>\chemicaltwintiparrow{#2}{#3}, - -=>\singlechemicalbond, - --=>\doublechemicalbond, - ---=>\triplechemicalbond, - \s!unknown=>\enablechemicalspecials - \chemicalmolecule{\commalistelement}{#2}{#3}]}} - -%\def\dosimplechemicalA#1#2#3% -% {\let\chemicalspace=\relax -% \def\dodosimplechemical##1% -% {\dosimplechemical{##1}{}{}}% -% \@EA\processcommalist\@EA[\@@chemicalchemicaloffset,#1]\dodosimplechemical -% \egroup} - -\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax} - {\let\chemicalspace=\relax - \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}% - \egroup} - -\def\dosimplechemicalB#1#2#3% - {\dosimplechemical{#1}{#2}{#3}% - \egroup} - -\def\dosimplechemicalC#1#2#3% - {$\simplechemical{#1}{#2}{#3}$% - \egroup} % erbij - -\def\simplechemical - {\ifinner - \innerchemicaltrue - \else - \innerchemicalfalse - \fi - \bgroup - \catcode`\^=\@@superscript % t.b.v. \enableduplication - \catcode`\_=\@@subscript % t.b.v. de zekerheid - \ifmmode - \ifinnerchemical - \def\next{\dotriplegroupempty\dosimplechemicalA}% - \else - \def\next{\dotriplegroupempty\dosimplechemicalB}% - \fi - \else - \def\next{\dotriplegroupempty\dosimplechemicalC}% - \fi - \next} - -\definecomplexorsimple\chemical - -\def\dogotochemical#1#2% - {\def\dowithchemical% % experiment - {\localgotochemical{#1}}% % experiment - \chemical} % experiment - -\def\gotochemical% % experiment - {\dosingleargument\dogotochemical} % experiment - -\def\dododochemical#1[#2][#3]% % experiment - {\def\simpledododochemical% % experiment - {#1[#2][#3]}% % experiment - \def\complexdododochemical[##1]% % experiment - {\def\dowithchemical% % experiment - {\localthisischemical{#2}}% % experiment - #1[#3][##1]}% % experiment - \complexorsimple\dododochemical} % experiment - -\def\dodochemical[#1][#2]% - {\ignorespaces - \ifinchemical - \drawchemical[#1][#2]% - \ignorespaces - \else - \startchemical[\c!location=\v!intext]% - \drawchemical[#1][#2]% - \expandafter\stopchemical - \fi - \ignorespaces} - -\def\dochemical[#1]% - {\def\simpledochemical% - {\@@writechemicalstate{ppchtex}{[#1][]}% - \dodochemical[#1][]}% - % - \def\complexdochemical[##1]% - {\@@writechemicalstate{ppchtex}{[#1][##1]}% - \txtchemical=0% - \dodochemical[#1][##1]}% - % - \def\complexdochemical[##1]% % experiment - {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment - \txtchemical=0% % experiment - \dododochemical\dodochemical[#1][##1]}% % experiment - % - \complexorsimple\dochemical} - -% \processlocalchemicals{#1} -% -% #1: commando's - -\def\dodoprocesschemical#1% - {\processchemical[#1????]} - -\def\processlocalchemicals#1% - {\processcommalist[#1]\dodoprocesschemical} - -% \drawchemical[#1][#2] -% -% #1: bindingen enz. -% #2: atomen enz. - -\def\localdodochemical[#1][#2]% - {\@@writechemicalstate{ppchtex}{[#1][#2]}% - %\bgroup % koppelen en afmetingen gaat fout, vandaar: - \advance\levchemical 1 - \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical - \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}% - \txtchemical=0 - \dodochemical[#1][#2]% - % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname - \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname - \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname - \advance\levchemical -1 - %\egroup - \ignorespaces} - -\def\drawchemical[#1][#2]% - {\ignorespaces - \def\dodochemical[##1][##2]% - {\drawchemical[##1][##2]% - \ignorespaces}% - \def\dochemical[##1]% - {\def\simpledochemical% - {\@@writechemicalstate{ppchtex}{[##1][#2]}% - \dodochemical[##1][#2]% - \ignorespaces}% - \def\complexdochemical[####1]% - {\dododochemical\localdodochemical[##1][####1,#2]}% - \complexorsimple\dochemical}% - \doif\@@chemicalstate\v!start - {\doifelse\chemicalname\s!unknown - {\getvalue{\s!executechemical\defaultchemical}[#2]} - {\getvalue{\s!executechemical\chemicalname}[#2]}% - \def\unknownchemical##1% - {\processunknownchemical[##1][#2]}% - \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}% - \ignorespaces} - -\unexpanded\def\chemicaloxidation#1#2#3% - {\chemicaltop - {\ifnum#20=0 - 0% - \else - #1\expandafter\uppercase\expandafter{\romannumeral#2}% - \fi} - {#3}} - -\def\chemicaltfraction{\ifinchemical.60\else.8\fi} -\def\chemicalbfraction{\ifinchemical.45\else.6\fi} -\def\chemicallfraction{\ifinchemical.1\else.1\fi} -\def\chemicalrfraction{\ifinchemical.1\else.1\fi} - -\def\chemicaltighttext - {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}% - \def\chemicalbfraction{\ifinchemical.2\else.4\fi}% - \def\chemicallfraction{\ifinchemical 0\else 0\fi}% - \def\chemicalrfraction{\ifinchemical 0\else 0\fi}} - -\def\dochemicaltop#1#2#3#4% - {\vbox - {\@@dochemicalcolor - \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt - \halign - {#1###2\cr - $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr - $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}} - -\def\dochemicalbottom#1#2#3#4% - {\vtop - {\@@dochemicalcolor - \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt - \halign - {#1###2\cr - $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr - $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}} - -\def\chemicalleft#1#2% - {\hbox - {\@@dochemicalcolor - $\@@dochemicalstyle{\scriptscriptstyle#1}$% - $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} - -\def\chemicalright#1#2% - {\hbox - {\@@dochemicalcolor - $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% - $\@@dochemicalstyle{\scriptscriptstyle#1}$}} - -\def\chemicalcentered#1% - {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}% - \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% - \dimen0=.5\ht2 - \advance\dimen0 by -.5\ht0 - \advance\dimen0 by \dp0 - \hbox{\@@dochemicalcolor\raise\dimen0\box0}} - -\def\chemicalleftcentered#1#2% - {\hbox - {\@@dochemicalcolor - \chemicalcentered{#1}% - $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} - -\def\chemicalrightcentered#1#2% - {\hbox - {\@@dochemicalcolor - $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% - \chemicalcentered{#1}}} - -\def\chemicaltop {\dochemicaltop \hss \hss } -\def\chemicallefttop {\dochemicaltop \relax \hss } -\def\chemicalrighttop {\dochemicaltop \hss \relax} -\def\chemicalbottom {\dochemicalbottom \hss \hss } -\def\chemicalleftbottom {\dochemicalbottom \relax \hss } -\def\chemicalrightbottom {\dochemicalbottom \hss \relax} - -\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}} -\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}} -\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}} -\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}} - -\def\chemicalsmashedleft#1% - {\hbox\bgroup - \@@dochemicalcolor - \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% - \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% - \wd2=\wd0 - \box2 - \egroup} - -\def\chemicalsmashedmiddle#1% - {\hbox\bgroup - \@@dochemicalcolor - \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% - \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% - \hbox{\hskip-.5\wd2\hskip.5\wd0\box2} - \egroup} - -\def\chemicalsmashedright#1% - {\hbox\bgroup - \@@dochemicalcolor - \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% - \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% - \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}% - \egroup} - -\def\+{\tabalign} % is \long in Plain - -\def\chemicalforever#1#2% - {\bgroup - \setbox0=\hbox - {\@@dochemicalcolor - $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}% - \wd0=0pt - \big#1_{\hskip.1em\box0}% - \egroup} - -\def\disablechemicalspecials% - {\def\+##1{##1}\def\-##1{##1}% - \def\[{[}\def\]{]}% - \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}% - \def\X{}% - \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}% - \def\TL{}\def\BL{}\def\TR{}\def\BR{}% - \def\LT{}\def\LB{}\def\RT{}\def\RB{}% - \def\SL{}\def\SM{}\def\SR{}} - -\def\enablechemicalspecials% - {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed! - \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed! - \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed! - \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed! - \def\1{\chemicaloxidation\relax1}% - \def\2{\chemicaloxidation\relax2}% - \def\3{\chemicaloxidation\relax3}% - \def\4{\chemicaloxidation\relax4}% - \def\5{\chemicaloxidation\relax5}% - \def\6{\chemicaloxidation\relax6}% - \def\7{\chemicaloxidation\relax7}% - \def\X{\chemicaltighttext}% - \def\T{\chemicaltop}% - \def\B{\chemicalbottom}% - \def\L{\chemicalleft}% - \def\LC{\chemicalleftcentered}% - \def\R{\chemicalright}% - \def\RC{\chemicalrightcentered}% - \def\TL{\chemicaltopleft}% - \def\BL{\chemicalbottomleft}% - \def\TR{\chemicaltopright}% - \def\BR{\chemicalbottomright}% - \def\LT{\chemicallefttop}% - \def\LB{\chemicalleftbottom}% - \def\RT{\chemicalrighttop}% - \def\RB{\chemicalrightbottom}% - \def\SL{\chemicalsmashedleft}% - \def\SM{\chemicalsmashedmiddle}% - \def\SR{\chemicalsmashedright}} - -% \reversechemical#1#2#3 -% -% #1: prefix -% #2: volgnummer enz -% #3: tegengestelde volgnummers - -\def\reversechemical#1#2#3% - {\def\doprocess[##1##2]% - {\doifchemicalnumber{##1}{#1#2}% - {\getfromcommalist[#3][##1]% - \let\reversechemicalaction=\commalistelement - \processchemical[#1\reversechemicalaction##2]}}% - \doprocess[#2]} - -% \processunknownchemical[#1????][#2] -% -% #1: bindingen enz. -% #2: atomen enz. - -\def\defaultchemical% - {SIX} - -\def\processunknownchemical[#1????][#2]% - {\processaction - [#1] - [ SAVE=>\executechemicalSAVE, - RESTORE=>\executechemicalRESTORE, - HIGH=>\sethighsubscripts, - LOW=>\setlowsubscripts, - \s!default=>, - \s!unknown=>\doifdefinedelse{\s!executechemical#1} - {\def\chemicalrotation{1}% - \def\chemicaloffset{0}% - \doifdefined{\s!executechemical#1} - {\getvalue{\s!executechemical#1}[#2]}% - \@@chemicalpostponed} - {\getpredefinedchemical{#1}}]} - -\newcount\chemicalstack % tzt \newwounter - -\setvalue{\s!chemical\c!x1}{0} -\setvalue{\s!chemical\c!y1}{0} - -\def\executechemicalSAVE - {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}% - \advance\chemicalstack by 1 - \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname - %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed - \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}% - \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}} - -\def\restorechemicalvalues#1% - {\let\oldprocesschemical=\processchemical - \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}% - \let\processchemical=\oldprocesschemical} - -\def\executechemicalRESTORE - {\ifnum\chemicalstack=0\relax - \horchemical=\getvalue{\s!chemical x1}\relax - \verchemical=\getvalue{\s!chemical y1}\relax - \else - \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}% - %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname - \let\@@chemicalpostponed=\relax - \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax - \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax - \advance\chemicalstack by -1 - \fi - \restorechemicalcoordinates} - -% De onderstaande macro's zijn verantwoordelijk voor het zetten -% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog -% gehaald. Dit oogt m.i. fraaier. - -\def\chemicalinnerclip#1% - {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}} - -\def\chemicalraise#1#2% - {\chemicalinnerclip - {\setbox0=\hbox{$#1+$}% - \raise\dp0\hbox{$#1#2$}}} - -\def\chemicalinnersign#1% todo: \@@chemicaltextcolor - {\chemicalraise{\@@localchemicalstyle}{#1}} - -\def\chemicaloutersign#1% - {\chemicalraise{}{\@@dochemicalcolor#1}} - -\def\chemicalsingleinnerarrow#1#2% - {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}} - -\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor - {\chemicalinnerclip - {\lower.2ex\hbox - {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}% - \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}% - \wd0=0pt\raise\ht0\box0\box2}}} - -\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor - {\chemicalinnerclip - {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}% - \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}% - \wd0=0pt\box0\box2}} - -\def\dochemicalouterarrow#1#2#3% - {\bgroup - \setbox0=\hbox{$\longrightarrow$}% - \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}% - \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}% - \dimen2=\wd0 % \dimen0 is used elsewhere - \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi - \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi - \chemicaloutermolecule - {#1} - {\ifdim\ht2>\!!zeropoint\box2\fi} % expands to \empty in test - {\ifdim\ht4>\!!zeropoint\box4\fi}% % expands to \empty in test - \egroup} - -\def\chemicalsingleouterarrow - {\dochemicalouterarrow - {\hbox to \dimen2{\rightarrowfill}}} - -\def\chemicaldoubleouterarrow - {\dochemicalouterarrow - {\lower.5\ht0\vbox - {\offinterlineskip - \hbox to \dimen2{\rightarrowfill} - \hbox to \dimen2{\leftarrowfill}}}} - -\def\chemicaltwintipouterarrow - {\dochemicalouterarrow - {\hbox - {\hbox to \dimen2{\rightarrowfill}% - \hskip-\dimen2 - \hbox to \dimen2{\leftarrowfill}}}} - -\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space - {\chemicalspace % todo: \@@chemicaltextcolor - \chemicalinnerclip - {\dosetsubscripts - $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$% - \doresetsubscripts}% - \chemicalspace} - -\def\chemicaloutermolecule#1#2#3% - {\chemicalspace - \bgroup - \@@dochemicalcolor - \setbox0=\hbox % else the font is reset - {\dosetsubscripts - \hbox{$\@@dochemicalstyle{\strut#1}$}% - \doresetsubscripts}% - \mathop{\box0}% - \ifthirdargument - \doifnot{#2}{} - {^{\@@dochemicalstyle{\strut#2}}}% - \doifnot{#3}{} - {_{\@@dochemicalstyle{\strut#3}}}% - \else - \doifnot{#2}{} - {_{\@@dochemicalstyle{\strut#2}}}% - \fi - \egroup - \chemicalspace} - -\def\chemicalsinglepicturearrow#1% - {\lower.5ex\hbox - {\@@dochemicalstyle - $\chemicalspace - \buildrel - \@@dochemicalstyle{\scriptstyle\quad#1\quad}% - \over{\overrightarrow - {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}% - \chemicalspace$}} - -\def\chemicaldoublepicturearrow#1% - {\lower.5ex\hbox - {\@@dochemicalstyle - $\chemicalspace - \buildrel - \@@dochemicalstyle{\scriptstyle\quad#1\quad}% - \over{\overrightarrow{\overleftarrow - {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}% - \chemicalspace$}} - -% Bij de in-line bindingen wordt gebruik gemaakt van -% een \hrule. De maatvoering wordt bepaald door een -% kunstmatige em (\wd0). - -\def\somechemicalbond% - {\hrule width \wd0 height .4pt} - -\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle - {{\setbox0=\hbox - {${\@@localchemicalstyle M}$}% - \vbox to \ht0 - {\@@dochemicalcolor - \hsize\wd0 - \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}} - -\def\singlechemicalbond% - {\dochemicalbonds{}{\somechemicalbond}{}} - -\def\doublechemicalbond% - {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}} - -\def\triplechemicalbond% - {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}} - -% In plaats van \def\naam{\chemie[...]...} kan beter gebruik -% worden gemaakt van het commando -% -% \definieerchemie[naam]{commando's} -% -% De naam krijgt, om problemen met bestaande macro's te -% voorkomen, een prefix. Bij het ophalen van een commando -% worden beide definities afgehandeld. - -\def\dodefinechemical[#1]#2% - {\doifdefined{\??chemical#1} - {\writestatus{ppchtex}{chemical definition #1 is redefined}}% - \setvalue{\??chemical#1}{#2}} - -\def\definechemical% - {\dosingleargument\dodefinechemical} - -\def\getpredefinedchemical#1% - {\doifdefinedelse{\??chemical#1} - {\getvalue{\??chemical#1}} - {\doifdefinedelse{#1} - {\getvalue{#1}} - {\writestatus{ppchtex}{unknown chemical definition #1}}}} - -% Hieronder zijn de definities van de structuren opgenomen. De -% naam van de structuur is als volgt opgebouwd: -% -% \executechemicalNUMBER[#1] -% -% waarbij [#1] betrekking heeft op de tekstelementen van \chemie, -% de [tweede lijst] dus. -% -% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt -% deels door de in \execute gedefinieerde macro's afgehandeld, -% deels door algemene macro's. Segmenten hebben de vorm: -% -% [+|-|]identifier[X|XYZ|X..Y] -% -% Voorbeelden van segmenten zijn: -% -% R1 -% R1..4 -% R135 -% -R1 -% +R35 - -\setchemicalmaximum 0 - -\def\processchemical[#1]% - {\unknownchemical{#1}} - -\def\setchemicalname#1 % - {\def\chemicalname{#1}} - -\let\chemicalname=\s!unknown - -% Vooruitlopend op een gedetailleerde documentatie, zijn hier -% vast enkele gebruikte afmetingen: -% -% lengte radikalen : 500 -% afstand radikalen : 100 -% afstand dubbele radikalen : 260 -% afstand substituenten : +125 - -\def\executechemicalONE[#1]% - {\setchemicalname ONE - % - \setchemicalmaximum 8 - \setchemicaldistance 0 - \setchemicalsubstitute 625 - \setchemicaldirection 303 - % - \setchemicalrotation 1 1 0 1 0 1 0 1 0 - \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 - \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1 - \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 - \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0 - \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 - \setchemicalrotation 7 0 1 0 1 0 1 0 1 - \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 45 135 225 315 - \setchemicalangle 3 90 180 270 0 - \setchemicalangle 4 135 225 315 45 - \setchemicalangle 5 180 270 0 90 - \setchemicalangle 6 225 315 45 135 - \setchemicalangle 7 270 0 90 180 - \setchemicalangle 8 315 45 135 225 - % - \setchemicaltranslate 1 -1000 0 - \setchemicaltranslate 2 -1000 1000 - \setchemicaltranslate 3 0 1000 - \setchemicaltranslate 4 1000 1000 - \setchemicaltranslate 5 1000 0 - \setchemicaltranslate 6 1000 -1000 - \setchemicaltranslate 7 0 -1000 - \setchemicaltranslate 8 -1000 -1000 - % - \setchemicallinesegment SB 300 0 700 0 - \setchemicallinesegment DB1 300 50 700 50 - \setchemicallinesegment DB2 300 -50 700 -50 - % - %setchemicallinesegment EP 200 125 200 -125 - \setchemicalfactorlinesegment EP 200 125 200 -125 - % - \setchemicaltextelement ES 200 0 - \setchemicaltextelement ED1 200 50 - \setchemicaltextelement ED2 200 -50 - \setchemicaltextelement ET1 200 75 - \setchemicaltextelement ET2 200 0 - \setchemicaltextelement ET3 200 -75 - \setchemicaltextelement HB1 300 0 - \setchemicaltextelement HB2 475 0 - \setchemicaltextelement HB3 650 0 - % - \setchemicaltextelement Z 800 0 - \setchemicaltextelement RZ 950 0 - \setchemicaltextelement ZN 500 0 - \setchemicaltextelement ZTN 500 150 - \setchemicaltextelement ZBN 500 -150 - % - \def\processchemical[##1##2##3##4##5]% - {\doprocesschemical[##1##2##3##4##5] - {\processaction - [##1##2##3##4##5] - [ PB:##4##5=>\beginchemicalpicture{##4##5}, - PE????=>\endchemicalpicture, - SUB##4##5=>\processchemicalsubstitute{##4##5}, - ADJ##4##5=>\processchemicaldistance{##4##5}, - MOV##4##5=>\processchemicaltranslate{##4##5}, - DIR##4##5=>\processchemicaldirection{##4##5}, - OFF##4##5=>\processchemicaloffset{##4##5}, - CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, - LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}% - \processchemicallinesegment{DB2}{##4##5}, - RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}% - \processchemicaldashedlinesegment{DB2}{##4##5}, - OF##3:##5=>\processchemicalphantom{##3}{##5}, - OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5}, - EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5}, - ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0}, - ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0}, - ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0}, - HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0}, - SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, - DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, - SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, - BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5}, - SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5}, - TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}% - \processchemicallinesegment{DB}{##3##4##5}, - CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{}, - ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0}, - ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{}, - ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0}, - ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{}, - ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, - ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, - Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0} - {l,l,t,r,r,r,b,l}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}} - -\def\executechemicalTHREE[#1]% - {\setchemicalname THREE - % - \setchemicalmaximum 3 - \setchemicaldistance 289 - \setchemicalsubstitute 952 - % - \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 - \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 - \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 120 210 300 30 - \setchemicalangle 3 240 330 60 150 - % - \setchemicaltranslate 1 -1000 0 - \setchemicaltranslate 2 0 1000 - \setchemicaltranslate 3 1000 0 - \setchemicaltranslate 4 0 -1000 - % - \setchemicallinesegment B 577 0 -289 -500 - \setchemicallinesegment SB 352 -130 -64 -370 - \setchemicallinesegment -SB 352 -130 -289 -500 - \setchemicallinesegment +SB 577 0 -64 -370 - \setchemicallinesegment DB1 327 -87 -89 -327 - \setchemicallinesegment DB2 377 -172 -39 -413 - \setchemicallinesegment R 577 0 1077 0 - \setchemicallinesegment -R 577 0 1010 250 - \setchemicallinesegment +R 577 0 1010 -250 - \setchemicallinesegment ER1 577 50 1077 50 - \setchemicallinesegment ER2 577 -50 1077 -50 - \setchemicallinesegment SR 837 0 1077 0 - \setchemicallinesegment -SR 802 130 1010 250 - \setchemicallinesegment +SR 802 -130 1010 -250 - \setchemicallinesegment DR1 837 50 1077 50 - \setchemicallinesegment DR2 837 -50 1077 -50 - % - \setchemicaltextelement Z 577 0 - \setchemicaltextelement RZ 1177 0 - \setchemicaltextelement -RZ 1097 300 - \setchemicaltextelement +RZ 1097 -300 - \setchemicaltextelement CRZ 1077 0 - % - \def\processchemical[##1##2##3##4]% - {\processaction - [##1##2##3##4] - [ ROT##4=>\processchemicalrotation{##4}, - MOV##4=>\processchemicaltranslate{##4}, - SUB##4=>\processchemicalsubstitute{##4}, - ADJ##4=>\processchemicaldistance{##4}, - -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3} - {l,t,r, l,r,l, r,b,l, r,l,r}, - +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3} - {l,r,b, r,r,l, r,l,t, l,l,r}, - -SB##4=>\processchemicallinesegment{-SB}{##4}, - +SB##4=>\processchemicallinesegment{+SB}{##4}, - -SR##4=>\processchemicallinesegment{-SR}{##4}, - +SR##4=>\processchemicallinesegment{+SR}{##4}, - CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0} - {}, - DB##3##4=>\processchemicallinesegment{DB}{##3##4}, - DR##3##4=>\processchemicallinesegment{DR}{##3##4}, - RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3} - {l,r,r, t,r,l, r,l,l, b,l,r}, - ER##3##4=>\processchemicallinesegment{ER}{##3##4}, - SB##3##4=>\processchemicallinesegment{SB}{##3##4}, - SR##3##4=>\processchemicallinesegment{SR}{##3##4}, - -R##3##4=>\processchemicallinesegment{-R}{##3##4}, - +R##3##4=>\processchemicallinesegment{+R}{##3##4}, - B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, - R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, - Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -\def\executechemicalFOUR[#1]% - {\setchemicalname FOUR - % - \setchemicalmaximum 4 - \setchemicaldistance 500 - \setchemicalsubstitute 0 - % - \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 - \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 - \setchemicalrotation 3 -1 0 0 1 1 0 0 -1 - \setchemicalrotation 4 0 1 1 0 0 -1 -1 0 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 90 180 270 0 - \setchemicalangle 3 180 270 0 90 - \setchemicalangle 4 270 0 90 180 - % - \setchemicaltranslate 1 -1000 0 - \setchemicaltranslate 2 0 1000 - \setchemicaltranslate 3 1000 0 - \setchemicaltranslate 4 0 -1000 - % - \setchemicallinesegment B 500 500 500 -500 - \setchemicallinesegment SB 500 240 500 -240 - \setchemicallinesegment -SB 500 240 500 -500 - \setchemicallinesegment +SB 500 500 500 -240 - \setchemicallinesegment DB1 450 240 450 -240 - \setchemicallinesegment DB2 550 240 550 -240 - \setchemicallinesegment EB 360 300 360 -300 - \setchemicallinesegment R 500 500 854 854 - \setchemicallinesegment -R 500 500 500 1000 - \setchemicallinesegment +R 500 500 1000 500 - \setchemicallinesegment ER1 465 535 819 889 - \setchemicallinesegment ER2 535 465 889 819 - \setchemicallinesegment SR 684 684 854 854 - \setchemicallinesegment -SR 500 760 500 1000 - \setchemicallinesegment +SR 760 500 1000 500 - \setchemicallinesegment DR1 649 719 819 889 - \setchemicallinesegment DR2 719 649 889 819 - % - \setchemicaltextelement Z 500 500 - \setchemicaltextelement RZ 925 925 - \setchemicaltextelement -RZ 500 1100 - \setchemicaltextelement +RZ 1100 500 - \setchemicaltextelement CRZ 1038 1038 - % - \setchemicaltextelement ZN 350 350 - % - \def\processchemical[##1##2##3##4]% - {\processaction - [##1##2##3##4] - [ PB:##4=>\beginchemicalpicture{##4}, - PE????=>\endchemicalpicture, - ROT##4=>\processchemicalrotation{##4}, - SUB##4=>\processchemicalsubstitute{##4}, - ADJ##4=>\processchemicaldistance{##4}, - MOV##4=>\processchemicaltranslate{##4}, - -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4} - {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t}, - +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4} - {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, - -SB##4=>\processchemicallinesegment{-SB}{##4}, - +SB##4=>\processchemicallinesegment{+SB}{##4}, - -SR##4=>\processchemicallinesegment{-SR}{##4}, - +SR##4=>\processchemicallinesegment{+SR}{##4}, - CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, - ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, - ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, - DB##3##4=>\processchemicallinesegment{DB}{##3##4}, - DR##3##4=>\processchemicallinesegment{DR}{##3##4}, - EB##3##4=>\processchemicallinesegment{EB}{##3##4}, - ER##3##4=>\processchemicallinesegment{ER}{##3##4}, - RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4} - {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt}, - SB##3##4=>\processchemicallinesegment{SB}{##3##4}, - SR##3##4=>\processchemicallinesegment{SR}{##3##4}, - -R##3##4=>\processchemicallinesegment{-R}{##3##4}, - +R##3##4=>\processchemicallinesegment{+R}{##3##4}, - B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, - R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, - Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -\def\executechemicalFIVE[#1]% - {\setchemicalname FIVE - % - \setchemicalmaximum 5 - \setchemicaldistance 688 - \setchemicalsubstitute 1226 - % - \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 - \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309 - \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809 - \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809 - \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 72 162 252 342 - \setchemicalangle 3 144 234 324 54 - \setchemicalangle 4 216 306 36 126 - \setchemicalangle 5 288 18 108 198 - % - \setchemicaltranslate 1 -1376 0 - \setchemicaltranslate 2 -425 1304 - \setchemicaltranslate 3 1113 809 - \setchemicaltranslate 4 1113 -809 - \setchemicaltranslate 5 -425 -1304 - % - \setchemicallinesegment A 1188 500 1188 -500 - \setchemicallinesegment B 688 500 688 -500 - \setchemicallinesegment S -263 808 688 -500 - \setchemicallinesegment SS -116 606 541 -298 - \setchemicallinesegment -SS -263 808 541 -298 - \setchemicallinesegment +SS -116 606 688 -500 - \setchemicallinesegment SB 688 240 688 -240 - \setchemicallinesegment -SB 688 240 688 -500 - \setchemicallinesegment +SB 688 500 688 -240 - \setchemicallinesegment DB1 638 240 638 -240 - \setchemicallinesegment DB2 738 240 738 -240 - \setchemicallinesegment EB 548 340 548 -340 - \setchemicallinesegment R 688 500 1093 794 - \setchemicallinesegment -R 688 500 688 1000 - \setchemicallinesegment +R 688 500 1163 345 - \setchemicallinesegment ER1 659 540 1064 834 - \setchemicallinesegment ER2 727 460 1122 754 - \setchemicallinesegment SR 898 653 1093 794 - \setchemicallinesegment -SR 688 760 688 1000 - \setchemicallinesegment +SR 935 420 1163 345 - \setchemicallinesegment DR1 869 693 1064 834 - \setchemicallinesegment DR2 927 613 1122 754 - % - \setchemicaltextelement Z 688 500 - \setchemicaltextelement RZ 1188 863 - \setchemicaltextelement -RZ 688 1100 - \setchemicaltextelement +RZ 1258 315 - \setchemicaltextelement CRZ 1323 947 - % - \setchemicalcircsegment C -36 36 590 72 475 -345 - \setchemicalcircsegment CC -72 0 590 72 182 -561 - % - \setchemicaltextelement ZN 468 350 - \setchemicaltextelement RN 860 625 % 1.25 Z - \setchemicaltextelement RTN 785 728 % .12 / 103 75 - \setchemicaltextelement RBN 935 522 - % - \def\processchemical[##1##2##3##4]% - {\processaction - [##1##2##3##4] - [ FRONT????=>{\executechemicalFIVEFRONT[#1]}, - PB:##4=>\beginchemicalpicture{##4}, - PE????=>\endchemicalpicture, - ROT##4=>\processchemicalrotation{##4}, - SUB##4=>\processchemicalsubstitute{##4}, - ADJ##4=>\processchemicaldistance{##4}, - MOV##4=>\processchemicaltranslate{##4}, - -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5} - {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r}, - +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5} - {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r}, - -SB##4=>\processchemicallinesegment{-SB}{##4}, - +SB##4=>\processchemicallinesegment{+SB}{##4}, - -SR##4=>\processchemicallinesegment{-SR}{##4}, - +SR##4=>\processchemicallinesegment{+SR}{##4}, - -RD##4=>\processchemicaldashedlinesegment{-R}{##4}, - +RD##4=>\processchemicaldashedlinesegment{+R}{##4}, - -RB##4=>\processchemicaldeltalinesegment{-R}{##4}, - +RB##4=>\processchemicaldeltalinesegment{+R}{##4}, - CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, - RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0}, - RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{}, - RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0}, - RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{}, - -SS##4=>\processchemicallinesegment{-SS}{##4}, - +SS##4=>\processchemicallinesegment{+SS}{##4}, - CCD##4=>\processchemicaldottsegment{CC}{##4}, - SS##3##4=>\processchemicallinesegment{SS}{##3##4}, - RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4}, - RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4}, - ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, - ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, - RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0}, - RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{}, - AU##3##4=>\processchemicaluparrowsegment{A}{##3##4}, - AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4}, - CC##3##4=>\processchemicalcircsegment{CC}{##3##4}, - CD##3##4=>\processchemicaldottsegment{C}{##3##4}, - DB##3##4=>\processchemicallinesegment{DB}{##3##4}, - DR##3##4=>\processchemicallinesegment{DR}{##3##4}, - EB##3##4=>\processchemicallinesegment{EB}{##3##4}, - ER##3##4=>\processchemicallinesegment{ER}{##3##4}, - RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5} - {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r}, - SB##3##4=>\processchemicallinesegment{SB}{##3##4}, - SR##3##4=>\processchemicallinesegment{SR}{##3##4}, - -R##3##4=>\processchemicallinesegment{-R}{##3##4}, - +R##3##4=>\processchemicallinesegment{+R}{##3##4}, - B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, - C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4}, - R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, - S##2##3##4=>\processchemicallinesegment{S}{##2##3##4}, - Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -\def\executechemicalSIX[#1]% - {\setchemicalname SIX - % - \setchemicalmaximum 6 - \setchemicalsubstitute 1375 - \setchemicaldistance 866 - % - \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 - \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5 - \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 - \setchemicalrotation 4 -1 0 0 1 1 0 0 -1 - \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 - \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 60 150 240 330 - \setchemicalangle 3 120 210 300 30 - \setchemicalangle 4 180 270 0 90 - \setchemicalangle 5 240 330 60 150 - \setchemicalangle 6 300 30 120 210 - % - \setchemicaltranslate 1 -1732 0 - \setchemicaltranslate 2 -866 1500 - \setchemicaltranslate 3 866 1500 - \setchemicaltranslate 4 1732 0 - \setchemicaltranslate 5 866 -1500 - \setchemicaltranslate 6 -866 -1500 - % - \setchemicallinesegment A 1386 500 1386 -500 - \setchemicallinesegment S 0 1000 866 -500 - \setchemicallinesegment SS 125 783 741 -283 - \setchemicallinesegment -SS 0 1000 741 -283 - \setchemicallinesegment +SS 125 783 866 -500 - \setchemicallinesegment B 866 500 866 -500 - \setchemicallinesegment SB 866 240 866 -240 - \setchemicallinesegment -SB 866 240 866 -500 - \setchemicallinesegment +SB 866 500 866 -240 - \setchemicallinesegment DB1 816 240 816 -240 - \setchemicallinesegment DB2 916 240 916 -240 - \setchemicallinesegment EB 726 340 726 -340 - \setchemicallinesegment R 866 500 1299 750 - \setchemicallinesegment -R 866 500 866 1000 - \setchemicallinesegment +R 866 500 1299 250 - \setchemicallinesegment ER1 841 543 1274 793 - \setchemicallinesegment ER2 891 457 1324 707 - \setchemicallinesegment SR 1091 630 1299 750 - \setchemicallinesegment -SR 866 740 866 1000 - \setchemicallinesegment +SR 1091 370 1299 250 - \setchemicallinesegment DR1 1066 673 1274 793 - \setchemicallinesegment DR2 1116 588 1324 707 - \setchemicallinesegment MID1 0 1000 -150 200 - \setchemicallinesegment MID2 0 -1000 -150 -200 - \setchemicallinesegment MIDS1 0 1000 -180 0 - \setchemicallinesegment MIDS2 0 -1000 -180 0 - % - \setchemicalcircsegment C -30 30 700 60 600 -346 - \setchemicalcircsegment CC -60 0 700 60 350 -606 - % - \setchemicaltextelement Z 866 500 - \setchemicaltextelement RZ 1386 800 - \setchemicaltextelement -RZ 866 1100 - \setchemicaltextelement +RZ 1386 200 - \setchemicaltextelement CRZ 1524 880 - \setchemicaltextelement MIDZ -150 0 - % - \setchemicaltextelement ZN 589 350 - \setchemicaltextelement RN 1083 625 % 1.25 Z - \setchemicaltextelement RTN 1008 755 % .12 / 130 75 - \setchemicaltextelement RBN 1158 495 - % - \def\processchemical[##1##2##3##4##5]% - {\processaction - [##1##2##3##4##5] - [ FRONT????=>{\executechemicalSIXFRONT[#1]}, - MID????=>\processchemicallinesegment{MID}{1????}, - MIDS????=>\processchemicallinesegment{MIDS}{1????}, - MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{}, - PB:##4##5=>\beginchemicalpicture{##4##5}, - PE????=>\endchemicalpicture, - ROT##4##5=>\processchemicalrotation{##4##5}, - SUB##4##5=>\processchemicalsubstitute{##4##5}, - ADJ##4##5=>\processchemicaldistance{##4##5}, - MOV##4##5=>\processchemicaltranslate{##4##5}, - -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6} - {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r}, - +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6} - {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r}, - -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, - +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, - -SR##4##5=>\processchemicallinesegment{-SR}{##4##5}, - +SR##4##5=>\processchemicallinesegment{+SR}{##4##5}, - -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5}, - +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5}, - -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5}, - +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5}, - CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{}, - -SS##4##5=>\processchemicallinesegment{-SS}{##4##5}, - +SS##4##5=>\processchemicallinesegment{+SS}{##4##5}, - CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, -RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0}, -RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{}, -RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0}, -RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{}, - SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5}, - RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5}, - RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5}, - ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, - ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, -RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0}, -RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{}, - AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5}, - AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5}, - CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5}, - CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5}, - DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, - EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5}, - ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5}, - RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6} - {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r}, - SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, - SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5}, - DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5}, - -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5}, - +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5}, - B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, - C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5}, - R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5}, - S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5}, - Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} - -\def\executechemicalSEVEN[#1]% incomplete ! - {\setchemicalname SEVEN - % - \setchemicalmaximum 7 - \setchemicalsubstitute - - \setchemicaldistance 1038 - % - \setchemicalrotation 1 .623 .782 - - - - - - - \setchemicalrotation 2 -.223 .975 - - - - - - - \setchemicalrotation 3 -.901 .434 - - - - - - - \setchemicalrotation 4 -.901 -.434 - - - - - - - \setchemicalrotation 5 -.223 -.975 - - - - - - - \setchemicalrotation 6 .623 -.782 - - - - - - - \setchemicalrotation 7 1 0 - - - - - - - % - \setchemicalangle 1 0 - - - - \setchemicalangle 2 51.429 - - - - \setchemicalangle 3 102.857 - - - - \setchemicalangle 4 154.286 - - - - \setchemicalangle 5 205.714 - - - - \setchemicalangle 6 257.143 - - - - \setchemicalangle 7 308.571 - - - - % - \setchemicaltranslate 1 - - - \setchemicaltranslate 2 - - - \setchemicaltranslate 3 - - - \setchemicaltranslate 4 - - - \setchemicaltranslate 5 - - - \setchemicaltranslate 6 - - - \setchemicaltranslate 7 - - - % - \setchemicallinesegment B 1038 500 1038 -500 - \setchemicallinesegment SB 1038 240 1038 -240 - \setchemicallinesegment -SB 1038 240 1038 -500 - \setchemicallinesegment +SB 1038 500 1038 -240 - % - \setchemicaltextelement Z 1038 500 - % - \def\processchemical[##1##2##3##4##5]% - {\processaction - [##1##2##3##4##5] - [ PB:##4##5=>\beginchemicalpicture{##4##5}, - PE????=>\endchemicalpicture, - %ROT##4##5=>\processchemicalrotation{##4}, - %SUB##4##5=>\processchemicalsubstitute{##4##5}, - %ADJ##4##5=>\processchemicaldistance{##4##5}, - %MOV##4##5=>\processchemicaltranslate{##4##5}, - -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, - +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, - SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, - B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, - Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} - -\def\executechemicalEIGHT[#1]% incomplete ! - {\setchemicalname EIGHT - % - \setchemicalmaximum 8 - %\setchemicalsubstitute 1307 - \setchemicaldistance 1207 - % - \setchemicalrotation 1 .707 .707 - - - - - - - \setchemicalrotation 2 0 1 - - - - - - - \setchemicalrotation 3 -.707 .707 - - - - - - - \setchemicalrotation 4 -1 0 - - - - - - - \setchemicalrotation 5 -.707 -.707 - - - - - - - \setchemicalrotation 6 0 -1 - - - - - - - \setchemicalrotation 7 .707 -.707 - - - - - - - \setchemicalrotation 8 1 0 - - - - - - - % - \setchemicalangle 1 45 - - - - \setchemicalangle 2 90 - - - - \setchemicalangle 3 135 - - - - \setchemicalangle 4 180 - - - - \setchemicalangle 5 225 - - - - \setchemicalangle 6 270 - - - - \setchemicalangle 7 315 - - - - \setchemicalangle 8 0 - - - - % - \setchemicaltranslate 1 -2414 0 - \setchemicaltranslate 2 -1706 1706 - \setchemicaltranslate 3 0 2414 - \setchemicaltranslate 4 1706 1706 - \setchemicaltranslate 5 2414 0 - \setchemicaltranslate 6 1706 -1706 - \setchemicaltranslate 7 0 -2414 - \setchemicaltranslate 8 -1706 -1706 - % - \setchemicallinesegment B 1207 500 1207 -500 - \setchemicallinesegment SB 1207 240 1207 -240 - \setchemicallinesegment -SB 1207 240 1207 -500 - \setchemicallinesegment +SB 1207 500 1207 -240 - % - \setchemicaltextelement Z 1207 500 - % - \def\processchemical[##1##2##3##4##5]% - {\processaction - [##1##2##3##4##5] - [ PB:##4##5=>\beginchemicalpicture{##4##5}, - PE????=>\endchemicalpicture, - %SUB##4##5=>\processchemicalsubstitute{##4##5}, - ADJ##4##5=>\processchemicaldistance{##4##5}, - MOV##4##5=>\processchemicaltranslate{##4##5}, - -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, - +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, - SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, - B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, - Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} - -\def\executechemicalFIVEFRONT[#1]% - {\executechemicalFIVE[]% - % - \setchemicalname FIVEFRONT - % - \setchemicallinesegment -R 688 500 688 100 - \setchemicallinesegment +R 688 500 688 900 - % - \setchemicaltextelement -RZ 0 -1300 - \setchemicaltextelement +RZ 0 1300 - % - \def\processchemical[##1##2##3##4]% - {\def\chemicalrotation{2}% - \processaction - [##1##2##3##4] - [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5} - {,,,,, t,t,t,t,t}, - +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5} - {,,,,, b,b,b,b,b}, - -SB##4=>\processchemicallinesegment{-SB}{##4}, - +SB##4=>\processchemicallinesegment{+SB}{##4}, - SB##3##4=>\processchemicallinesegment{SB}{##3##4}, - -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, - +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, - BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, - R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% - \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, - B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, - Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -\def\executechemicalSIXFRONT[#1]% - {\executechemicalSIX[]% - % - \setchemicalname SIXFRONT - % - \setchemicallinesegment -R 866 500 866 100 - \setchemicallinesegment +R 866 500 866 900 - % - \setchemicaltextelement -RZ 0 -1300 - \setchemicaltextelement +RZ 0 1300 - % - \def\processchemical[##1##2##3##4]% - {\def\chemicalrotation{2}% - \processaction - [##1##2##3##4] - [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6} - {,,,,,, t,t,t,t,t,t}, - +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6} - {,,,,,, b,b,b,b,b,b}, - -SB##4=>\processchemicallinesegment{-SB}{##4}, - +SB##4=>\processchemicallinesegment{+SB}{##4}, - SB##3##4=>\processchemicallinesegment{SB}{##3##4}, - -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, - +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, - BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, - R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% - \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, - B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, - Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -% 1 : 0 -% 2 : -115 -% 3* : -195 -% 3 : -165 -% 4 : -245 - -\def\executechemicalCARBON[#1]% - {\setchemicalname CARBON - % - \setchemicalmaximum 4 - \setchemicaldistance 0 - \setchemicalsubstitute 0 - % - \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 - \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423 - \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966 - \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966 - \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423 - % - \setchemicalangle 1 0 90 180 270 - \setchemicalangle 2 115 205 295 25 - \setchemicalangle 3 165 255 345 75 - \setchemicalangle 3* 195 285 15 105 - \setchemicalangle 4 245 335 65 155 - % - \setchemicaltranslate 1 -1500 0 - \setchemicaltranslate 2 0 1500 - \setchemicaltranslate 3 1500 0 - \setchemicaltranslate 4 0 -1500 - % - \setchemicallinesegment B1 500 0 1000 0 - \setchemicallinesegment B2 300 0 1000 0 - \setchemicallinesegment B3 500 0 1000 0 - \setchemicallinesegment B4 300 0 1000 0 - % - \setchemicaltextelement Z 1100 0 - % - \setchemicalcircsegment C 0 360 500 360 0 -500 - % - \def\processchemical[##1##2##3##4##5]% - {\processaction - [##1##2##3##4##5] - [ MIR????=>\setchemicalmirror{3}, - -MIR????=>\resetchemicalmirror{3}, - *MIR????=>\togglechemicalmirror{3}, - CB????=>\processlocalchemicals{B,C,Z}, - C????=>\processchemicalcircsegment{C}{1????}, - -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2}, - ROT##4##5=>\processchemicalrotation{##4##5}, - MOV##4##5=>\processchemicaltranslate{##4##5}, - CB##3##4##5=>\processlocalchemicals - {ROT##3,C,B,Z2..4, - MOV##3,*MIR,-ROT##3,C,B,Z2..4}, - B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5}, - Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4} - {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} - -% 1: 45 2: -90 3: -225 -% 4: -45 5: -135 6: -270 - -\newif\ifNEWMANstagger \NEWMANstaggertrue - -\def\executechemicalNEWMANSTAGGER% - {\NEWMANstaggertrue\executechemicalNEWMAN} - -\def\executechemicalNEWMANECLIPSE% - {\NEWMANstaggerfalse\executechemicalNEWMAN} - -\def\executechemicalNEWMAN[#1]% - {\setchemicalname NEWMAN - % - \setchemicalmaximum 6 - \setchemicaldistance 0 - \setchemicalsubstitute 0 - % - \ifNEWMANstagger - \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707 - \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 - \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707 - \else - \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866 - \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259 - \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5 - \fi - \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707 - \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707 - \setchemicalrotation 6 0 1 1 0 0 -1 -1 0 - % - \ifNEWMANstagger - \setchemicalangle 1 315 45 135 225 - \setchemicalangle 2 90 180 270 0 - \setchemicalangle 3 225 315 45 135 - \else - \setchemicalangle 1 30 120 210 300 - \setchemicalangle 2 255 345 75 165 - \setchemicalangle 3 120 210 300 30 - \fi - \setchemicalangle 4 45 135 225 315 - \setchemicalangle 5 135 225 315 45 - \setchemicalangle 6 270 0 90 180 - % - \setchemicaltranslate 1 -1500 0 - \setchemicaltranslate 2 0 1500 - \setchemicaltranslate 3 1500 0 - \setchemicaltranslate 4 0 -1500 - % - \setchemicallinesegment B1 0 0 1000 0 - \setchemicallinesegment B2 0 0 1000 0 - \setchemicallinesegment B3 0 0 1000 0 - \setchemicallinesegment B4 500 0 1000 0 - \setchemicallinesegment B5 500 0 1000 0 - \setchemicallinesegment B6 500 0 1000 0 - % - \setchemicaltextelement Z 1100 0 - % - \setchemicalcircsegment C 0 360 500 360 0 -500 - % - \def\processchemical[##1##2##3##4]% - {\processaction - [##1##2##3##4] - [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]}, - ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]}, - B????=>\processlocalchemicals{B1..6}, - CB????=>\processlocalchemicals{B1..6,C,Z1..6}, - C????=>\processchemicalcircsegment{C}{1????}, - ROT##4=>\processchemicalrotation{##4}, - MOV##4=>\processchemicaltranslate{##4}, - B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4}, - Z##2##3##4=>\ifNEWMANstagger - \processchemicaltextelement{Z}{##2##3##4}{#1}{6} - {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}% - \else - \processchemicaltextelement{Z}{##2##3##4}{#1}{6} - {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}% - \fi, - \s!unknown=>\unknownchemical{##1##2##3##4}]}} - -\def\executechemicalCHAIR[#1]% smaller - {\setchemicalname CHAIR - % - \setchemicalmaximum 6 - % - \setchemicallinesegment B1 1600 800 2800 -800 - \setchemicallinesegment B2 2800 -800 800 0 - \setchemicallinesegment B3 800 0 -1600 -800 - \setchemicallinesegment B4 -1600 -800 -2800 800 - \setchemicallinesegment B5 -2800 800 -800 0 - \setchemicallinesegment B6 -800 0 1600 800 - % - \setchemicallinesegment +R1 1600 800 1600 1600 - \setchemicallinesegment +R2 2800 -800 2800 -1600 - \setchemicallinesegment +R3 800 0 800 800 - \setchemicallinesegment +R4 -1600 -800 -1600 -1600 - \setchemicallinesegment +R5 -2800 800 -2800 1600 - \setchemicallinesegment +R6 -800 0 -800 -800 - % - \setchemicallinesegment -R1 1600 800 2350 522 % 750 278 - \setchemicallinesegment -R2 2800 -800 3493 -400 - \setchemicallinesegment -R3 800 0 1329 -600 % 528 600 - \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278 - \setchemicallinesegment -R5 -2800 800 -3493 400 - \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600 - % - \setchemicaltextelement +RZ1 1600 1800 - \setchemicaltextelement +RZ2 2800 -1800 - \setchemicaltextelement +RZ3 800 1000 - \setchemicaltextelement +RZ4 -1600 -1800 - \setchemicaltextelement +RZ5 -2800 1800 - \setchemicaltextelement +RZ6 -800 -1000 - % - \setchemicaltextelement -RZ1 2538 453 % 200 lang - \setchemicaltextelement -RZ2 3666 -300 - \setchemicaltextelement -RZ3 1460 -750 - \setchemicaltextelement -RZ4 -2538 -453 - \setchemicaltextelement -RZ5 -3666 300 - \setchemicaltextelement -RZ6 -1460 750 - % - \def\processchemical[##1##2##3##4##5]% - {\def\chemicalrotation{1}% - \processaction - [##1##2##3##4##5] - [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6}, - -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6}, - +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6}, - B##2????=>{\getchemicallinesegment[0][B##2]}, - -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]}, - +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]}, - -R##3????=>{\getchemicallinesegment[0][-R##3]}, - +R##3????=>{\getchemicallinesegment[0][+R##3]}, - \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} - -\def\executechemicalarrow#1#2[#3]% - {\dogetcommalistelement1\from#3\to\toptext - \dogetcommalistelement2\from#3\to\bottext - \def\dochemicaltext##1% - {\dosetsubscripts% - $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$% - \doresetsubscripts}% - \doifelse\@@chemicallocation\v!intext - {#1{\dochemicaltext\toptext}}% - {\setbox\chemicalsymbols=\hbox - {\box\chemicalsymbols - \vbox{\halign{##\cr - \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr - #2% - \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}} - -\def\executechemicalGIVES - {\executechemicalarrow - {\chemicalsinglepicturearrow}% nodig - {\rightarrowfill\cr}} - -\def\executechemicalEQUILIBRIUM - {\executechemicalarrow - {\chemicaldoublepicturearrow}% nodig - {\rightarrowfill\cr\leftarrowfill\cr}} - -\def\executechemicalMESOMERIC - {\executechemicalarrow - {\chemicalsinglepicturearrow}% nodig - {$\leftarrow\hskip-1em$\rightarrowfill\cr}} - -\def\executechemicalsign#1[#2]% - {\doifelse\@@chemicallocation\v!intext - {\dosetsubscripts - $\@@dochemicalstyle{\@@localchemicalformat#1}$% - \doresetsubscripts} - {\setbox\chemicalsymbols\hbox - {\box\chemicalsymbols - \dosetsubscripts - $\@@dochemicalstyle{\@@localchemicalformat#1}$% - \doresetsubscripts}}} - -\def\executechemicalPLUS - {\executechemicalsign{+}} - -\def\executechemicalMINUS - {\executechemicalsign{-}} - -\def\executechemicalEQUAL - {\executechemicalsign{=}} - -\def\executechemicalSPACE[#1]% - {\doifnot\@@chemicallocation\v!intext - {\setbox\chemicalsymbols\hbox - {\box\chemicalsymbols - \quad}}} - -\def\executechemicalCHEM[#1]% - {\doifnot\@@chemicallocation\v!intext - {\setbox\chemicalsymbols\hbox - {\box\chemicalsymbols - $\@@dochemicalstyle{\@@localchemicalformat#1}$}}} - -\def\executechemicalTEXT[#1]% - {\doifnot\@@chemicallocation\v!intext - {\setbox\chemicalsymbols\hbox - {\box\chemicalsymbols#1}}} - -%\def\executechemicalLOW[#1]% -% {\setlowsubscripts} -% -%\def\executechemicalHIGH[#1]% -% {\sethighsubscripts} - -\def\putchemicalrule#1#2#3#4% - {\ifcase\chemicaldrawingmode - \putrule from {#1} {#2} to {#3} {#4} - \or - \psline(#1,#2)(#3,#4)% - \or - \bgroup - \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax - \global\MPdrawingdonetrue - \setchemicalattributes - \startMPdrawing - x1 := \MPdivten[\the\!!counta]u ; - y1 := \MPdivten[\the\!!countb]u ; - x2 := \MPdivten[\the\!!countc]u ; - y2 := \MPdivten[\the\!!countd]u ; - draw z1--z2 ; - \stopMPdrawing - \egroup - \fi} - -\def\executechemicalcomplex#1% - {\bgroup - \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}% - \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}% - \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}% - \egroup} - -\def\executechemicalOPENCOMPLEX[#1]% - {\executechemicalcomplex+\ignorespaces - \executechemicalSPACE[]} - -\def\executechemicalCLOSECOMPLEX[#1]% - {\executechemicalSPACE[]% - \executechemicalcomplex-\ignorespaces} - -% nog niet door midden as! - -\def\executechemicalverticalsymbol#1#2% - {\executechemicalTEXT - [$\left#1\relax - \dimen0=\@@chemicalunit - \scratchcounter=\@@chemicaltop - \advance\scratchcounter by \@@chemicalbottom - \dimen0=\scratchcounter\dimen0 - \vcenter to \dimen0{} - \dimen2=\@@chemicalunit - \dimen2=\@@chemicalright\dimen0 - \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}% - \right.$]}% - -\def\executechemicalUPARROW[#1]% - {\executechemicalverticalsymbol\uparrow{#1}} - -\def\executechemicalDOWNARROW[#1]% - {\executechemicalverticalsymbol\downarrow{#1}} - -\def\executechemicalUPDOWNARROW[#1]% - {\executechemicalverticalsymbol\updownarrow{#1}} - -\let\setchemicalattributes\relax - -\setupchemical - [\c!width=0, - \c!height=0, - \c!left=0, - \c!right=0, - \c!top=0, - \c!bottom=0, - \c!bodyfont=\the\bodyfontsize, - \c!resolution=\outputresolution, - \c!scale=\v!medium, - \c!size=\v!medium, - \c!textsize=\v!big, - \c!frame=\v!off, - \c!axis=\v!off, - \c!state=\v!start, - \c!style=\rm, - \c!location=, - \c!option=, - \c!offset=LOW, - \c!alternative=1, - \c!color=, - \c!rulethickness=, - \c!rulecolor=, - \c!factor=1] - -% Tijdelijk plaatsen we deze extra macro's hier. -% -% mathontop: \mtop {} {} -% textontop: \ttop {} {} - -\def\putontop#1#2% - {\vbox - {\halign - {\strut\hss##\hss\cr - #1\cr - #2\cr}}} - -\def\ttop#1#2% - {\putontop{\tx#1}{#2}} - -\def\mtop#1#2% - {\vbox - {\offinterlineskip - \halign - {\hss##\hss\cr - $\scriptscriptstyle#1$\cr - \noalign{\vskip.5ex}% - $#2$\cr}}} - -\def\ctop#1#2% - {\vbox - {\offinterlineskip - \halign - {\hss##\hss\cr - $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr - \noalign{\vskip.5ex}% - $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}} - -%D Here are a couple of \CONTEXT\ goodies: -%D -%D \startitemize -%D \item styles hooked into \CONTEXT\ style mechanism -%D \item support for color and rulethickness (mp mode only) -%D \item position tracking -%D \stopitemize - - -\ifCONTEXT \else \protect \endinput \fi - -\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} - -\let\@@chemicalcolor\empty - -\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.mkii b/tex/context/base/prop-ini.mkii new file mode 100644 index 000000000..035a40c93 --- /dev/null +++ b/tex/context/base/prop-ini.mkii @@ -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 + {\setgvalue{\e!start#1}{\dostartproperty{#1}}% + \letgvalue{\e!stop #1}\dostopproperty}% + {\setgvalue{\e!start#1}{\dostartgproperty{#1}}% + \letgvalue{\e!stop #1}\dostopgproperty}}% + {\doifelsevalue{\??py#1\c!global}\v!yes + {\setgvalue{\e!start#2}[##1]{\dostartproperty{##1}}% + \letgvalue{\e!stop #2}\dostopproperty}% + {\setgvalue{\e!start#2}[##1]{\dostartgproperty{##1}}% + \letgvalue{\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-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-ini.tex b/tex/context/base/prop-ini.tex deleted file mode 100644 index 084842fdd..000000000 --- a/tex/context/base/prop-ini.tex +++ /dev/null @@ -1,151 +0,0 @@ -%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\defineproperty - {\dotripleempty\dodefineproperty} - -\def\dodefineproperty[#1]% - {\ifundefined{\??py#1\c!global}% - \expandafter\dododefineproperty - \else - \expandafter\nododefineproperty - \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 ! ! ! ! - \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 - \letgvalue{\??py\s!check#1}\docheckproperty - \doifelsevalue{\??py#1\c!method}\v!command - {\doifelsevalue{\??py#1\c!global}\v!yes - {\setgvalue{\e!start#1}{\dostartproperty{#1}}% - \letgvalue{\e!stop #1}\dostopproperty}% - {\setgvalue{\e!start#1}{\dostartgproperty{#1}}% - \letgvalue{\e!stop #1}\dostopgproperty}}% - {\doifelsevalue{\??py#1\c!global}\v!yes - {\setgvalue{\e!start#2}[##1]{\dostartproperty{##1}}% - \letgvalue{\e!stop #2}\dostopproperty}% - {\setgvalue{\e!start#2}[##1]{\dostartgproperty{##1}}% - \letgvalue{\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--

Regimes take care of converting the input characters into sequences. The conversion tables are loaded at runtime.

--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--

We will hook regime handling code into the input methods.

--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-- -

The following code is rather specific.

---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-- +

The following code is rather specific.

+--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 + -- + -- + -- + -- 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.mkiv b/tex/context/base/sort-def.mkiv deleted file mode 100644 index 8cc92a02e..000000000 --- a/tex/context/base/sort-def.mkiv +++ /dev/null @@ -1,16 +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. - -% nothing here - -\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-- -

This module implements a couple of cleanup methods. We need these -in order to meet the specification. Watch the double -parenthesis; they are needed because otherwise we would pass more -than one argument to .

---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 {<>}% - \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} @@ -1047,32 +1047,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 @@ -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/strc-blk.lua b/tex/context/base/strc-blk.lua new file mode 100644 index 000000000..33dbb0b7c --- /dev/null +++ b/tex/context/base/strc-blk.lua @@ -0,0 +1,145 @@ +if not modules then modules = { } end modules ['strc--blk'] = { + version = 1.001, + 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" +} + +-- this one runs on top of buffers and structure + +local texprint, format, gmatch = tex.print, string.format, string.gmatch + +local ctxcatcodes = tex.ctxcatcodes + +structure = structure or { } +structure.blocks = structure.blocks or { } + +local blocks = structure.blocks + +blocks.collected = blocks.collected or { } +blocks.tobesaved = blocks.tobesaved or { } +blocks.states = blocks.states or { } + +local tobesaved, collected, states = blocks.tobesaved, blocks.collected, blocks.states + +local function initializer() + collected, tobesaved = blocks.collected, blocks.tobesaved +end + +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(ctxcatcodes,format("\\dostarthiddenblock{%s}",name)) + else + texprint(ctxcatcodes,format("\\dostartnormalblock{%s}",name)) + end + if type(data) == "table" then + for i=1,#data do + texprint(data[i]) + end + else + printer:match(data) + end + if hide then + texprint(ctxcatcodes,"\\dostophiddenblock") + else + texprint(ctxcatcodes,"\\dostopnormalblock") + end +end + +function blocks.define(name) + states[name] = { all = "hide" } +end + +function blocks.setstate(state,name,tag) + local all = tag == "" + local tags = not all and aux.settings_to_array(tag) + for n in gmatch(name,"%s*([^,]+)") do + local sn = states[n] + if not sn then + -- error + elseif all then + sn.all = state + else + for _, tag in pairs(tags) do + sn[tag] = state + end + end + 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 + local names = aux.settings_to_set(name) + local all = tag == "" + 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, collected) + for i=1,#result do + local ri = result[i] + local metadata = ri.metadata + if names[metadata.name] then + if all then + blocks.print(name,ri.data,hide) + else + local mtags = metadata.tags + for tag, sta in pairs(tags) do + if mtags[tag] then + blocks.print(name,ri.data,hide) + break + end + end + end + end + end +end + +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 + tobesaved[#tobesaved+1] = { + metadata = { + name = name, + tags = tags, + plus = plus, + minus = minus, + }, + references = { + section = structure.sections.currentid(), + }, + data = data or "error", + } + local allstate = states[name].all + if not next(tags) then + if allstate ~= "hide" then + blocks.print(name,data) + elseif plus then + blocks.print(name,data,true) + end + else + local sn = states[name] + for tag, _ in pairs(tags) do + if sn[tag] == nil then + if allstate ~= "hide" then + blocks.print(name,data) + break + end + elseif sn[tag] ~= "hide" then + blocks.print(name,data) + break + end + end + end + buffers.data[buffer] = nil +end diff --git a/tex/context/base/strc-blk.tex b/tex/context/base/strc-blk.tex new file mode 100644 index 000000000..90d2ff9ab --- /dev/null +++ b/tex/context/base/strc-blk.tex @@ -0,0 +1,110 @@ +%D \module +%D [ file=strc-blk, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Blockmoves, +%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 / Blockmoves} + +\registerctxluafile{strc-blk}{1.001} + +\unprotect + +% we run on top of buffers and sections +% +% todo: prefix numbers (needs further integration elsewhere) +% check functionality +% alternative files (needs further integration elsewhere) + +\def\blockparameter#1#2{\ifcsname\??tb#1#2\endcsname\csname\??tb#1#2\endcsname\fi} + +\def\setupblockparameters{\dodoubleargument \dosetupblock} % fast one (for compatibility) +\def\setupblock {\dodoubleargumentwithset\dosetupblock} % handles set + +\def\dosetupblock[#1]{\getparameters[\??tb#1]} % [#1][#2]} + +\def\defineblock + {\dosingleargument\dodefineblock} + +\def\dodefineblock[#1]% + {\getparameters + [\??tb#1] + [\c!before=\blank, + \c!after=\blank, + \c!inner=, + \c!style=, + \c!file=]% todo + \ctxlua{structure.blocks.define("#1")}% + \setvalue{\e!begin#1}{\dodoubleempty\dobeginofblock[#1]}% + \letvalue{\e!end#1}\relax} + +\long\def\dobeginofblock[#1][#2]% + {\normalexpanded{\noexpand\dodowithbuffer{@block@}{\e!begin#1}{\e!end#1}} + {}{\ctxlua{structure.blocks.save("#1","#2","@block@")}}}% before after + +\def\dostarthiddenblock + {\startnointerference + \dostartnormalblock} + +\def\dostophiddenblock + {\dostopnormalblock + \stopnointerference} + +% order matters: \c!before (think of: \c!before=\startitemize) + +\let\doblocksetups\gobbleoneargument + +\def\dostartnormalblock#1% name + {\bgroup +\visibletrue + \edef\currentblock{#1}% + \doblocksetups\currentblock + \let\doblocksetups\gobbleoneargument + \blockparameter\currentblock\c!before + \dosetfontattribute{\??tb\currentblock}\c!style + \dosetcolorattribute{\??tb\currentblock}\c!color + \blockparameter\currentblock\c!inner + \ignorespaces} + +\def\dostopnormalblock + {\removeunwantedspaces + \blockparameter\currentblock\c!after + \par % todo: alternative = text, paragraph + \egroup} + +\def\dosetblockstate[#1][#2][#3]% state name tag + {\ctxlua{structure.blocks.setstate("#1","#2","#3")}} + +\def\doselectblocks[#1][#2][#3][#4]% state name tag setups + {\begingroup + \doifassignmentelse{#3} + {\getparameters[\??tb\??tb][\c!criterium=\v!text,#3]% + \def\doblocksetups##1{\getparameters[\??tb##1][#3]}% + \ctxlua{structure.blocks.select("#1","#2","","\@@tb@@tbcriterium")}} + {\getparameters[\??tb\??tb][\c!criterium=\v!text,#4]% + \def\doblocksetups##1{\getparameters[\??tb##1][#4]}% + \ctxlua{structure.blocks.select("#1","#2","#3","\@@tb@@tbcriterium")}}% + \endgroup} + +% hide: save, if [+] also hidden execute +% keep: save and normal execute + +\def\hideblocks{\dotripleempty\dosetblockstate[hide]} +\def\keepblocks{\dotripleempty\dosetblockstate[keep]} + +% use : normal execute unless [-] +% process: hidden execute unless [-] +% select : idem use + +\def\useblocks {\doquadrupleempty\doselectblocks[use]} +\def\processblocks{\doquadrupleempty\doselectblocks[process]} +\def\selectblocks {\doquadrupleempty\doselectblocks[use]} + +\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("<%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 {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 = + +\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 = + +\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 + + + + +
+ Some <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more + +

a paragraph of text

+

another paragraph of text

+
+
+
+ Another <b>bold</b> title <b>bold <i>bold</i> oeps</b> and more + +

a paragraph of text

+

another paragraph of text

+
+
+
+ +% 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{} + {\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 side.

--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.mkii b/tex/context/base/supp-ran.mkii new file mode 100644 index 000000000..d595fffaf --- /dev/null +++ b/tex/context/base/supp-ran.mkii @@ -0,0 +1,122 @@ +%D \module +%D [ file=supp-ran, +%D version=1998.01.21, +%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 \macros +%D {getrandomcount, getrandomdimen, +%D getrandomfloat, getrandomnumber, +%D setrandomseed, getrandomseed} +%D +%D This module load Donald Arseneau's generic file +%D \type{random.tex}. A small shell is needed because we +%D redefine some \TEX\ primitives. We also use different names +%D for the two generators and add an extra one. +%D +%D \starttyping +%D \getrandomcount \countregister {minimum} {maximum} +%D \getrandomdimen \dimenregister {minimum} {maximum} +%D \getrandomnumber \macroname {minimum} {maximum} +%D \getrandomfloat \macroname {minimum} {maximum} +%D \stoptyping +%D +%D Of course the file \type{random.tex} needs to be present. +%D To prevent name clashes, the \CONTEXT\ distribution +%D contains a copy in \type {thrd-ran.tex}. +%D +%D The randomseed can be set by: +%D +%D \starttyping +%d \setrandomseed{number>0} +%D \stoptyping +%D +%D and get by: +%D +%D \starttyping +%D \getrandomseed\randomseed +%D \stoptyping + +\input thrd-ran.tex + +\ifx\uniformdeviate\undefined + + \let\verynormalnextrandom\nextrandom + + \def\normalnextrandom + {\bgroup + \let\time \normaltime + \let\day \normalday + \let\month\normalmonth + \let\year \normalyear + \verynormalnextrandom + \egroup} + +\else + + \writestatus{loading}{using TeX's built in randomizer (overloading macro)} + + % 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. + + \def\nextrandom + {\normalsetrandomseed\randomi\relax + \global\randomi\numexpr\normaluniformdeviate2147483646+1\relax} + + \let\normalnextrandom\nextrandom + +\fi + +\def\nextrandom + {\bgroup + \normalnextrandom + \gdef\nextrandom{\ifcase\randomseedfrozen\normalnextrandom\fi}% + \egroup} + +\chardef\randomseedfrozen\zerocount + +\def\freezerandomseed + {\ifcase\randomseedfrozen + \nextrandom \global\chardef\randomseedfrozen\plusone + \fi} + +\def\defrostrandomseed + {\ifcase\randomseedfrozen\else + \global\chardef\randomseedfrozen\zerocount \nextrandom + \fi} + +\let\getrandomcount\setrannum +\let\getrandomdimen\setrandim + +\def\getrandomnumber#1#2#3% + {\getrandomcount\scratchcounter{#2}{#3}% + \edef#1{\the\scratchcounter}} + +\def\getrandomfloat#1#2#3% + {\getrandomdimen\scratchdimen{#2\points}{#3\points}% + \edef#1{\withoutpt\the\scratchdimen}} + +\unexpanded \def\setrandomseed#1% + {\global\randomi#1\relax} % global added + +\unexpanded \def\getrandomseed#1% + {\edef#1{\number\randomi}} + +\def\getnewrandomseed#1% + {\setrandomseed\minusone % signals thrd-ran to auto reseed + \nextrandom % this signal is needed for the + #1\randomi} % pseudo randomizer (see: third-ran) + +\endinput 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-ran.tex b/tex/context/base/supp-ran.tex deleted file mode 100644 index 8c76ab443..000000000 --- a/tex/context/base/supp-ran.tex +++ /dev/null @@ -1,158 +0,0 @@ -%D \module -%D [ file=supp-ran, -%D version=1998.01.21, -%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}{Third Party Macros / Random Number Generation} - -%D \macros -%D {getrandomcount, getrandomdimen, -%D getrandomfloat, getrandomnumber, -%D setrandomseed, getrandomseed} -%D -%D This module load Donald Arseneau's generic file -%D \type{random.tex}. A small shell is needed because we -%D redefine some \TEX\ primitives. We also use different names -%D for the two generators and add an extra one. -%D -%D \starttyping -%D \getrandomcount \countregister {minimum} {maximum} -%D \getrandomdimen \dimenregister {minimum} {maximum} -%D \getrandomnumber \macroname {minimum} {maximum} -%D \getrandomfloat \macroname {minimum} {maximum} -%D \stoptyping -%D -%D Of course the file \type{random.tex} needs to be present. -%D To prevent name clashes, the \CONTEXT\ distribution -%D contains a copy in \type {thrd-ran.tex}. -%D -%D The randomseed can be set by: -%D -%D \starttyping -%d \setrandomseed{number>0} -%D \stoptyping -%D -%D and get by: -%D -%D \starttyping -%D \getrandomseed\randomseed -%D \stoptyping - -\ifx\nextrandom\undefined - - \readfile{random.tex} - {\writestatus{loading}{Donald Arseneau's 'random.tex' (found)}} - {\writestatus{loading}{Donald Arseneau's 'random.tex' (not found)}} - -\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 - -\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} - -\else - - % Yet untested. - - \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 - - \beginETEX \numexpr - \def\nextrandom - {\normalsetrandomseed\randomi - \global\randomi\numexpr\normaluniformdeviate2147483646+1\relax} - \endETEX - - \let\normalnextrandom\nextrandom - -\fi - -\def\nextrandom - {\bgroup - \normalnextrandom - \gdef\nextrandom{\ifcase\randomseedfrozen\normalnextrandom\fi}% - \egroup} - -\chardef\randomseedfrozen\zerocount - -\def\freezerandomseed - {\ifcase\randomseedfrozen - \nextrandom \global\chardef\randomseedfrozen\plusone - \fi} - -\def\defrostrandomseed - {\ifcase\randomseedfrozen\else - \global\chardef\randomseedfrozen\zerocount \nextrandom - \fi} - -\let\getrandomcount\setrannum -\let\getrandomdimen\setrandim - -\def\getrandomnumber#1#2#3% - {\getrandomcount\scratchcounter{#2}{#3}% - \edef#1{\the\scratchcounter}} - -\def\getrandomfloat#1#2#3% - {\getrandomdimen\scratchdimen{#2\points}{#3\points}% - \edef#1{\withoutpt\the\scratchdimen}} - -\unexpanded \def\setrandomseed#1% - {\global\randomi#1\relax} % global added - -\unexpanded \def\getrandomseed#1% - {\edef#1{\number\randomi}} - -\def\getnewrandomseed#1% - {\setrandomseed\minusone % signals thrd-ran to auto reseed - \nextrandom % this signal is needed for the - #1\randomi} % pseudo randomizer (see: third-ran) - -\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-chr.tex b/tex/context/base/syst-chr.tex deleted file mode 100644 index 085d7429f..000000000 --- a/tex/context/base/syst-chr.tex +++ /dev/null @@ -1,131 +0,0 @@ -%D \module -%D [ file=syst-chr, -%D version=1997.01.03, % moved code -%D title=\CONTEXT\ System Macros, -%D subtitle=Character Related 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. - -\unprotect - -%D We want to have access to the raw alternatives of the -%D special characters. We use a \type {\xdef} instead of -%D \type {\let} because we need an expandable token in a -%D \type {\write}. - -\bgroup - -\catcode`B=\@@begingroup -\catcode`E=\@@endgroup -\catcode`.=\@@escape - -.catcode `.{ 12 .xdef .letteropenbrace B.string{E -.catcode `.} 12 .xdef .letterclosebrace B.string}E -.catcode `.& 12 .xdef .letterampersand B.string&E -.catcode `.< 12 .xdef .letterless B.string 12 .xdef .lettermore B.string>E -.catcode `.# 12 .xdef .letterhash B.string#E -.catcode `." 12 .xdef .letterdoublequote B.string"E -.catcode `.' 12 .xdef .lettersinglequote B.string'E -.catcode `.$ 12 .xdef .letterdollar B.string$E -.catcode `.% 12 .xdef .letterpercent B.string%E -.catcode `.^ 12 .xdef .letterhat B.string^E -.catcode `._ 12 .xdef .letterunderscore B.string_E -.catcode `.| 12 .xdef .letterbar B.string|E -.catcode `.~ 12 .xdef .lettertilde B.string~E -.catcode `.\ 12 .xdef .letterbackslash B.string\E -.catcode `./ 12 .xdef .letterslash B.string/E -.catcode `.? 12 .xdef .letterquestionmark B.string?E -.catcode `.! 12 .xdef .letterexclamationmark B.string!E -.catcode `.@ 12 .xdef .letterat B.string@E -.catcode `.: 12 .xdef .lettercolon B.string:E - - .global .let .letterescape .letterbackslash - .global .let .letterbgroup .letteropenbrace - .global .let .letteregroup .letterclosebrace - .global .let .letterleftbrace .letteropenbrace - .global .let .letterrightbrace .letterclosebrace - -.egroup - -%D \macros % check this one -%D {setcatcodes,uncatcodespecials, -%D uncatcodecharacters,uncatcodespacetokens, -%D setnaturalcatcodes, -%D setverbosecscharacters} -%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} - -\def\uncatcodespecials {\setcatcodetable\nilcatcodes \uncatcodespacetokens} -\def\setnaturalcatcodes {\setcatcodetable\nilcatcodes} -\def\setnormalcatcodes {\setcatcodetable\ctxcatcodes} % maybe \texcatcodes -\def\uncatcodecharacters {\setcatcodetable\nilcatcodes} % was fast version, gone now -\def\uncatcodeallcharacters{\setcatcodetable\nilcatcodes} % was slow one, with restore - -%D Next follows a definition that lets some shortcuts expand to -%D themselves. - -\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 - -%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} - -\def\frenchspacing - {\setfrenchspacing{1000}} - -\def\resetfrenchspacing - {\sfcode`\.3000 \sfcode`\,1250 - \sfcode`\?3000 \sfcode`\!3000 - \sfcode`\:2000 \sfcode`\;1500 } - -\protect \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 's char range but outside the unicode range.

--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 @@ -4641,44 +4656,6 @@ {\comparedresult\plustwo}} {\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 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 = control +\def\^^I{\ } % same for + +%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 = control -\def\^^I{\ } % same for - -%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/tabl-ltb.tex b/tex/context/base/tabl-ltb.tex new file mode 100644 index 000000000..e45fb1bc1 --- /dev/null +++ b/tex/context/base/tabl-ltb.tex @@ -0,0 +1,856 @@ +%D \module +%D [ file=core-ltb, +%D version=2002.10.31, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Line 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. + +% testfile: tfmetrics.tex + +% todo: als nx>1, dan in geval van rek tussenruimte berekenen en optellen +% bij breedte, dus: nx nog niet gebruiken in combinatie met rek ! ! ! ! ! + +% This module is experimental, undocumented, and currently only set up +% eTeX. It provides a mechanism for typesetting very large tables, +% spanning many pages horizontally and vertically, with repeated +% header lines and (entry) columns, tab tracking, color, etc. In does +% two passes over a table, which is why the table goes into a +% buffer or file. As said, tables can be real huge. + +% \BH \BC .. \EC \BC .. \EC \EH % append +% \BR \BC .. \EC \BC .. \EC \ER +% +% or +% +% \NC .. \NC .. \NC \NR (todo: optional last \NC) + +% alternative: +% +% (1) direct run, save content in macro, but only if needed +% +% todo +% +% (2) buffered table content +% +% \startbuffer +% \startlinetablehead +% \stoplinetablehead +% \startlinetablebody +% \stoplinetablebody +% \stopbuffer +% +% \processlinetablebuffer[buffer] +% +% in buffer : head and body +% +% (3) unbuffered run, multipass +% +% - run with starting width zero / prev run +% - clip on prev run +% - flush real widths + +\writestatus{loading}{ConTeXt Table Macros / Line Tables} + +\unprotect + +\chardef\linetablesplitstate\zerocount +\chardef\linetableheadstate \zerocount + +\edef\??ler{\??le:r:} +\edef\??lec{\??le:c:} +\edef\??lew{\??le:w:} +\edef\??leh{\??le:h:} +\edef\??led{\??le:d:} + +\newif\iflinetablepreroll +\newif\ifinlinetable + +\newcount\linetablecolumn +\newcount\linetablesubcol +\newdimen\linetablewidth +\newdimen\linetableheight +\newbox \linetablecell + +\let\noflinetablecolumns\!!zerocount +\let\noflinetablerows \!!zerocount +\let\noflinetablelines \!!zerocount +\let\noflinetableparts \!!zerocount +\let\linetablepart \!!plusone +\let\linetablestep \!!plusone +\let\linetableline \!!zerocount +\let\linetablerow \!!zerocount +\let\linetablerows \!!zerocount + +\initializetablebox \zerocount % holds repeater + +\chardef\linetablehmode \zerocount +\chardef\linetablepage \zerocount +\chardef\linetablerepeat\zerocount + +\def\setuplinetable + {\dotripleempty\dosetuplinetable} + +\def\dosetuplinetable[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??le:#1:#2][#3]% + \else\ifsecondargument + \getparameters[\??lec#1][#2]% + \else + \getparameters[\??le][#1]% + \fi\fi} + +\setuplinetable + [\c!n=\!!maxcard, + \c!lines=\!!maxcard, + \c!nx=\plusone, + \c!nleft=0, + \c!repeat=\v!yes, % when \c!nleft>0, repeat on both pages + \c!before=, + \c!after=, + \c!inbetween=\page, + \c!distance=\zeropoint, + \c!stretch=\v!no, + \c!align=\c!right, + \c!leftoffset=.25ex, + \c!rightoffset=\linetableparameter\c!leftoffset, + \c!maxwidth=\zeropoint, + \c!width=5em, + \c!height=\v!fit, % \v!line = faster + \c!background=, + \c!backgroundcolor=] + +\def\linetableparameter#1% + {\csname\??le#1\endcsname} + +\def\doifelselinetablecparameter#1% + {\ifcsname\??lec\number\linetablecolumn#1\endcsname + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\def\linetablecparameter#1% + {\csname + \ifcsname\??lec\number\linetablecolumn#1\endcsname + \??lec\number\linetablecolumn + \else + \??le + \fi + #1\endcsname} + +\def\linetablerparameter#1% faster, leaner and meaner + {\csname + \ifnum\linetablerow=\zerocount % geen ifcase + \ifcsname\??ler\v!header#1\endcsname + \??ler\v!header#1% + \else\ifcsname\??ler0#1\endcsname + \??ler0#1% + \else + \s!empty + \fi\fi + \else + \ifcsname\??ler\number\linetablerow#1\endcsname + \??ler\number\linetablerow#1% + \else\ifcsname\??ler\v!oddeven\linetablerow#1\endcsname + \??ler\v!oddeven\linetablerow#1% + \else + \s!empty + \fi\fi + \fi + \endcsname} + +\def\setnoftableslines + {\doifelse{\linetableparameter\c!lines}\v!fit + {% whitespace already added by vertical strut + \ifdim\pagegoal<\maxdimen + \scratchdimen\pagegoal + \advance\scratchdimen -\pagetotal + \else + \scratchdimen\textheight + \fi + \getrawnoflines\scratchdimen + \xdef\noflinetablelines{\the\noflines} +\iflinetablepreroll \else \ifnum\noflinetablelines<\plustwo + \page \setnoftableslines +\fi \fi +} + {\xdef\noflinetablelines{\linetableparameter\c!lines}}} + +\def\startlinetablecell + {\dosingleempty\dostartlinetablecell} + +\def\dostartlinetablecell[#1]% + {\global\setbox\linetablecell\hbox\bgroup + \iffirstargument + \getparameters[\??lec\number\linetablecolumn][#1]% + \fi + \xdef\linetablestep{\linetablecparameter\c!nx}% + \ifcase\linetablestep\or + \scratchdimen\linetablecparameter\c!width + \scratchskip \linetablecparameter\c!distance + \else + \scratchdimen \zeropoint + \scratchskip \zeropoint + \scratchcounter\linetablecolumn + \dorecurse\linetablestep + {\advance\scratchdimen\linetablecparameter\c!width + %\advance\scratchskip \linetablecparameter\c!distance + \global\advance \linetablecolumn\plusone + \advance\scratchskip \linetablecparameter\c!distance + }% + \global\linetablecolumn\scratchcounter + \fi + \chardef\linetablemode + \iflinetablepreroll + \ifdim\scratchdimen>\zeropoint \zerocount \else \plustwo \fi + \else + \zerocount + \fi + \ifcase\linetablemode + \ifcase\linetablehmode + % nothing + \or + % fit, keep it simple + \or + \chardef\linetablemode\plusone % line + \else + % some already calculated height + \fi + \fi + \setbox\scratchbox\hbox + \bgroup + \dontcomplain + \hskip\linetablecparameter\c!leftoffset\relax + % 0 = width, unknown height + % 1 = width, fixed height + % 2 = no width, auto hsize + \ifnum\linetablemode<\plustwo + \advance\scratchdimen-\linetablecparameter\c!leftoffset + \advance\scratchdimen-\linetablecparameter\c!rightoffset + \fi + \ifcase\linetablemode + \dosetraggedcommand{\linetablecparameter\c!align}% + \vtop \ifdim\linetableheight>\zeropoint to\linetableheight \fi \bgroup + \hsize\scratchdimen + \raggedcommand + \else + \setalignmentswitch{\linetablecparameter\c!align}% + \hbox \ifcase\linetablemode \or to\scratchdimen \fi \bgroup + \ifcase\alignmentswitch\hss\or\hss\fi + \fi + \dostartattributes{\??lec\number\linetablecolumn}\c!style\c!color\empty + \begstrut \ignorespaces} + +% \def\stoplinetablecell +% {\unskip \endstrut +% \dostopattributes +% \ifcase\linetablemode +% \endgraf +% \else +% \ifcase\alignmentswitch\else\hss\fi +% \fi +% \egroup +% \hskip\linetablecparameter\c!rightoffset +% \egroup +% \iflinetablepreroll +% \box\scratchbox +% \else +% \doif{\linetablecparameter\c!background}\v!color +% {\backgroundline[\linetablecparameter\c!backgroundcolor]}% +% {\box\scratchbox}% +% \fi +% \egroup} + +\newconditional\linetableautoheight \settrue\linetableautoheight + +\def\stoplinetablecell + {\unskip \endstrut + \dostopattributes + \ifcase\linetablemode + \endgraf + \else + \ifcase\alignmentswitch\else\hss\fi + \fi + \egroup + \hskip\linetablecparameter\c!rightoffset + \egroup + \iflinetablepreroll + \box\scratchbox + \else + \doifelse{\linetablecparameter\c!background}\v!color + {\ifconditional\linetableautoheight + \hbox{\blackrule + [ \c!color=\linetablecparameter\c!backgroundcolor, + \c!height=\linetablerparameter{x\c!height}, + \c!depth=\linetablerparameter{x\c!depth}, + \c!width=\wd\scratchbox]% + \hskip-\wd\scratchbox\box\scratchbox}% + \else + \backgroundline[\linetablecparameter\c!backgroundcolor]{\box\scratchbox}% + \fi}% + {\box\scratchbox}% + \fi + \egroup} + +% \def\stoplinetablecell +% {\unskip \endstrut +% \dostopattributes +% \ifcase\linetablemode +% \endgraf +% \else +% \ifcase\alignmentswitch\else\hss\fi +% \fi +% \egroup +% \hskip\linetablecparameter\c!rightoffset +% \egroup +% \iflinetablepreroll +% \box\scratchbox +% \else +% \doifelse{\linetablecparameter\c!background}\v!color +% {\ifconditional\linetableautoheight +% % \hbox{\blackrule +% % [ \c!color=\linetablecparameter\c!backgroundcolor, +% % \c!height=\linetablerparameter{x\c!height}, +% % \c!depth=\linetablerparameter{x\c!depth}, +% % \c!width=\wd\scratchbox]% +% % \hskip-\wd\scratchbox\box\scratchbox}% +% \dp\scratchbox\linetablerparameter{x\c!depth}% +% \ht\scratchbox\linetablerparameter{x\c!height}% +% \framed +% [\c!offset=\v!overlay, +% \c!frameoffset=.5\linewidth, +% \c!leftframe=\v!off,\c!rightframe=\v!off, +% \c!background=\v!color, +% \c!backgroundcolor=\linetablecparameter\c!backgroundcolor% +% ]{\box\scratchbox}% +% \else +% \backgroundline[\linetablecparameter\c!backgroundcolor]{\box\scratchbox}% +% \fi}% +% {\box\scratchbox}% +% \fi +% \egroup} + +\def\savelinetablepart + {\global\setbox\tablebox\linetablepart + \ifnum\linetablepart=\zerocount + \box\scratchbox % just storing + \else + \vbox + {\ifvoid\tablebox\linetablepart\else\unvbox\tablebox\linetablepart\fi + \doif{\linetablerparameter\c!background}\v!color + {\backgroundline[\linetablerparameter\c!backgroundcolor]}% + {\box\scratchbox}% is also arg to \backgroundline + \endgraf + \linetablerparameter\c!after}% + \fi} + +\def\flushlinetableparts + {\doglobal\increment\linetableline + \ifnum\linetableline<\noflinetablelines + % keep collecting + \else + \iflinetablepreroll + % forget about them + \else + \dorecurse\noflinetableparts + {\let\linetablepart\recurselevel + \dp\tablebox\linetablepart\strutdepth + % noindent en endgraf needed else whitespace mess-up! + \whitespace % here not after verticalstrut + \ifdim\topskipgap=\zeropoint\else + \verticalstrut\nobreak\kern-\struttotal\kern-\parskip\nobreak\nointerlineskip % fix topskip + \fi + \noindent\strut\hbox to \hsize{\box\tablebox\linetablepart\hss}\endgraf + \ifnum\linetablepart<\noflinetableparts\relax + \linetableparameter\c!inbetween + \fi}% + \ifnum\linetablerows<\noflinetablerows\relax + \linetableparameter\c!inbetween + \else + % after, later + \fi + \chardef\linetableheadstate\plusthree + \global\setbox\tablebox\zerocount\emptybox % here + \fi + % reset \linetablerow will be an option, currently + % starts at zero after split + \globallet\linetablerow\!!zerocount + \globallet\linetableline\!!zerocount + \global\chardef\linetablepage\zerocount + \global\linetablewidth\zeropoint + \setnoftableslines + \fi} + +\def\startlinetablepart + {\global\linetablesubcol\zerocount + \setbox\scratchbox\hbox\bgroup + \doconvertfont{\linetablerparameter\c!style}% + \startcolor[\linetablerparameter\c!color]% + \ignorespaces} + +\def\stoplinetablepart + {\ifnum\linetablepart>\zerocount + \unskip \unskip % remove last intercolumn skip (distance+fill) + \fi + \stopcolor + \egroup + \iflinetablepreroll \else + \ifcase\linetablepart + % we're collecting the repeater + \else + \scratchdimen\hsize \advance\scratchdimen-\wd\scratchbox\relax + \ifdim\scratchdimen>\linetableparameter\c!stretch\else + \setbox\scratchbox\hbox to \hsize{\unhbox\scratchbox}% + \fi + \fi + \fi} + +\def\checklinetablepart + {\global\advance\linetablewidth\wd\linetablecell + \global\advance\linetablecolumn\linetablestep + \global\advance\linetablesubcol\linetablestep + \relax + %\message{\the\linetablecolumn,\the\linetablesubcol}\wait + % from now on the column counter is already incremented + \ifcase\linetablesplitstate + \iflinetablepreroll \else + \box\linetablecell + % the columncounter is one ahead ! +% \hskip\linetablecparameter\c!afstand + \hskip\scratchskip + \fi + %%% + \donefalse + \ifcase\linetablerepeat\else + % van te voren berekenen + \scratchcounter\linetablecolumn\advance\scratchcounter-\plustwo + \ifnum\linetablerepeat=\scratchcounter + \donetrue % collecting repeater + \fi + \fi + %%%% + \ifdone + % collecting repeater + \else + \ifnum\linetablecolumn>\getvalue{\??le::\linetablepart}\relax + \donetrue + \fi + \fi + \ifdone + \stoplinetablepart + \iflinetablepreroll \else + \savelinetablepart + \fi + \ifcase\linetablepage \or + \global\chardef\linetablepage \plustwo + \else + \global\chardef\linetablepage \plusone + \fi + \doglobal\increment\linetablepart + \global\linetablewidth\wd\tablebox\zerocount + \startlinetablepart + \fi + \else + \donefalse + \!!doneafalse + \ifcase\linetablerepeat\else + % van te voren berekenen + \scratchcounter\linetablecolumn \advance\scratchcounter-\plustwo + \ifnum\linetablerepeat=\scratchcounter + \donetrue % collecting repeater + \fi + \fi + \ifdone + \!!doneatrue + % collecting repeater + \else\ifdim\linetablewidth>\hsize + \donetrue + \else +% \global\advance\linetablewidth\linetablecparameter\c!afstand\relax + \global\advance\linetablewidth\scratchskip + \ifdim\linetablewidth>\hsize % ? + \donetrue + \fi + \fi\fi + \ifdone + \stoplinetablepart + \savelinetablepart + \ifcase\linetablepage \or + \global\chardef\linetablepage \plustwo + \else + \global\chardef\linetablepage \plusone + \fi + \doglobal\increment\linetablepart + \ifnum\linetablepart>\noflinetableparts + \globallet\noflinetableparts\linetablepart + \initializetablebox\linetablepart + \fi + \global\linetablewidth\wd\linetablecell + \startlinetablepart + \if!!doneb \else \ifcase\linetablerepeat \else + % check for left/right page + \ifcase\linetablepage\donetrue\or\donetrue\or\donefalse\fi\ifdone + % insert repeater + \global\advance\linetablewidth\wd\tablebox\zerocount + \iflinetablepreroll\kern\wd\else\unhcopy\fi\tablebox\zerocount + \fi + \fi \fi + \fi + \iflinetablepreroll \else + \box\linetablecell + % the columncounter is one ahead ! +% \hskip\linetablecparameter\c!afstand +% \hskip\scratchskip +\dorecurse\linetablestep{\strut\hfil}% + \hskip\scratchskip + \fi + \fi} + +% \linetableparameter\c!var -> \@@levar (when no classes) + +\def\startlinetablerun % to do: quit when nested + {\bgroup + \inlinetabletrue + % autowidth + \doif{\linetableparameter\c!maxwidth}\v!fit + {\setuplinetable[\c!maxwidth=\zeropoint]}% + \processaction + [\linetableparameter\c!stretch] + [ \v!no=>{\setuplinetable[\c!stretch=\maxdimen]},% no stretch + \v!yes=>{\setuplinetable[\c!stretch=\zeropoint]}]% max stretch + \chardef\linetablerepeat\linetableparameter\c!nleft + \chardef\linetablesplitstate % = + \ifdim\linetableparameter\c!maxwidth>\zeropoint + \zerocount \else \plusone + \fi + % optional prevdepth correction + \iflinetablepreroll + \globallet\noflinetablerows\!!zerocount + \else + \linetableparameter\c!before + \fi + \globallet\linetablerows\!!zerocount + \globallet\noflinetablecolumns\!!zerocount + \globallet\noflinetableparts\!!zerocount + \!!counta\zerocount + \def\docommand##1% + {\doglobal\increment\noflinetableparts + \advance\!!counta##1% + \setxvalue{\??le::\noflinetableparts}{\the\!!counta}}% + \processcommacommand[\linetableparameter\c!n]\docommand + \initializetableboxes\noflinetableparts + \ifcase\linetablerepeat + \globallet\linetablepart\!!plusone + \else + \globallet\linetablepart\!!zerocount % repeater + \fi + \globallet\linetablestep\!!plusone + \globallet\linetableline\!!zerocount + \globallet\linetablerow \!!zerocount + \global\linetablecolumn \zerocount + \global\linetablesubcol \zerocount + \global\linetablewidth \zeropoint +\iflinetablepreroll \else \ifdim\pagetotal>\zeropoint + \verticalstrut\kern-\struttotal +\fi \fi + \setnoftableslines + \checklinetablepage + \let\BR\linetableBR + \let\ER\linetableER + \let\BH\linetableBR + \let\EH\linetableER + \let\BC\linetableBC + \let\EC\linetableEC + \let\NC\linetableNC + \let\NR\linetableNR + \flushlinetablehead} + +\def\stoplinetablerun + {\globallet\linetableline\!!maxcard + \chardef\linetableheadstate\zerocount % blocked + \flushlinetableparts + \iflinetablepreroll \else + \linetableparameter\c!after + \fi + \globallet\linetablepart \!!zerocount + \globallet\noflinetableparts\!!zerocount + \egroup} + +% \def\checklinecolumnwidth +% {\ifundefined{\??lew\number\linetablecolumn}% +% \donetrue +% \else\ifdim\getvalue{\??lew\number\linetablecolumn}<\wd\linetablecell +% \donetrue +% \else +% \donefalse +% \fi\fi +% \ifdone +% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% +% \fi} +% +% \def\checklinecolumnwidth +% {\ifcsname\??lew\number\linetablecolumn\endcsname +% \ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell +% \donetrue +% \else +% \donefalse +% \fi +% \else +% \donetrue +% \fi +% \ifdone +% \setxvalue{\??lew\number\linetablecolumn}{\the\wd\linetablecell}% +% \fi} + +% \def\checklinecolumnwidth +% {\expandafter\xdef\csname\??lew\number\linetablecolumn\endcsname +% {\expandafter\ifx\csname\??lew\number\linetablecolumn\endcsname\relax +% \the\wd\linetablecell +% \else\ifdim\csname\??lew\number\linetablecolumn\endcsname<\wd\linetablecell +% \the\wd\linetablecell +% \else +% \csname\??lew\number\linetablecolumn\endcsname +% \fi\fi}} + +\def\checklinecolumndimension#1#2#3% + {\expandafter\xdef\csname#1\number#3\endcsname + {\expandafter\ifx\csname#1\number#3\endcsname\relax + \the#2\linetablecell + \else\ifdim\csname#1\number#3\endcsname<#2\linetablecell + \the#2\linetablecell + \else + \csname#1\number#3\endcsname + \fi\fi}} + +\def\checklinecolumnwidth {\checklinecolumndimension\??lew\wd\linetablecolumn} +\def\checklinecolumnheight{\checklinecolumndimension\??leh\ht\linetablerow} +\def\checklinecolumndepth {\checklinecolumndimension\??led\dp\linetablerow} + +\def\linetableBR + {\dosingleempty\dolinetableBR} + +\def\dolinetableBR[#1]% #1 not yet implemented + {\ifnum\linetableheadstate=1\else + \doglobal\increment\linetablerow + \doglobal\increment\linetablerows + \fi + \global\linetablecolumn\plusone + \global\linetablesubcol\plusone +% \linetableheight\linetablerparameter\c!height +% +% \ifx\linetableheight\empty +% % nothing +% \else\ifx\linetableheight\v!fit +% % keep it simple +% \else\ifx\linetableheight\v!line +% \chardef\linetablemode\plusone +% \else +% \!!heighta\linetableheight +% \advance\!!heighta-\strutdepth +% \fi\fi\fi +% + \linetableheight\zeropoint + \edef\!!stringa{\linetablerparameter\c!height}% + \ifx\!!stringa\empty + \chardef\linetablehmode\zerocount + \else\ifx\!!stringa\v!fit + \chardef\linetablehmode\plusone + \else\ifx\!!stringa\v!line + \chardef\linetablehmode\plustwo + \else + \linetableheight\!!stringa + \advance\linetableheight-\strutdepth + \fi\fi\fi +% + \startlinetablepart} + +\def\linetableBC + {\startlinetablecell} + +\def\linetableEC + {\stoplinetablecell + \iflinetablepreroll + \checklinecolumnwidth + \checklinecolumnheight + \checklinecolumndepth + \fi + \checklinetablepart} + +\def\linetableER + {% \stoplinetablecell + % no \box\linetablecell, i.e. dummy columnn, last \NC \NR + \stoplinetablepart + \savelinetablepart + \advance\linetablecolumn \minusone + \ifnum\linetablecolumn>\noflinetablecolumns + \xdef\noflinetablecolumns{\number\linetablecolumn}% + \fi + \flushlinetableparts + \global\linetablecolumn\zerocount + \global\linetablewidth \zeropoint + \ifcase\linetablerepeat + \globallet\linetablepart\!!plusone + \else + \globallet\linetablepart\!!zerocount % repeater + \fi + \checklinetablepage + \flushlinetablehead} + +\def\checklinetablepage + {\global\chardef\linetablepage\zerocount + \ifcase\linetablerepeat \else \ifcase\linetablepage + \doif{\linetableparameter\c!repeat}\v!no + {\global\chardef\linetablepage\doifoddpageelse\plusone\plustwo}% + \fi \fi} + +\def\flushlinetablehead + {\ifcase\linetableheadstate + % 0 blocked + \or + % 1 doing head + \or + % 2 head done + \or + % 3 trigger flush + \chardef\linetableheadstate\plusone + \the\@@linetablehead\relax + \chardef\linetableheadstate\plustwo + \fi} + +\def\linetableNC % first time special treatment + {\relax + \ifcase\linetablecolumn + \linetableBR + \else + \linetableEC + \fi + \linetableBC} % beware, this will result in BR BC EC BC NR + +\def\linetableNR + {\stoplinetablecell % dummy + \linetableER} + +\def\startlinetable + {\startlinetablerun} + +\def\stoplinetable + {\stoplinetablerun} + +\def\startlinetableanalysis + {\bgroup + \linetableprerolltrue + \trialtypesettingtrue + \startlinetablerun} + +\def\stoplinetableanalysis + {\stoplinetablerun + \egroup + \globallet\noflinetablerows\linetablerows + \dorecurse\noflinetablerows % global, from last run {\linetableparameter\c!n} + {%\writestatus{linetable}{\recurselevel->\getvalue{\??lew\recurselevel}}% + \setevalue{\??ler\recurselevel x\c!height}{\getvalue{\??leh\recurselevel}}% + \setevalue{\??ler\recurselevel x\c!depth }{\getvalue{\??led\recurselevel}}% + \letgvalue{\??leh\recurselevel}\!!zeropoint + \letgvalue{\??led\recurselevel}\!!zeropoint} + \dorecurse\noflinetablecolumns % global, from last run {\linetableparameter\c!n} + {%\writestatus{linetable}{\recurselevel->\getvalue{\??lew\recurselevel}}% + \setevalue{\??lec\recurselevel\c!width}{\getvalue{\??lew\recurselevel}}% + \letgvalue{\??lew\recurselevel}\!!zeropoint}} % init next table + +% todo: store in box instead of macro + +\newtoks \@@linetablehead + +\long\def\startlinetablehead#1\stoplinetablehead + {\ifinlinetable + \@@linetablehead\emptytoks + \fi + \chardef\linetableheadstate3 % full + \@@linetablehead{#1}% + \ifinlinetable + \flushlinetablehead + \fi} + +\def\linetableBH + {\ifx\EC\relax + % signal, grabbing lines + \else + \@@linetablehead\emptytoks + \fi + \pushmacro\BC + \pushmacro\EC + \def\BC##1\EC{\appendtoks##1\to\@@linetablehead}% + \let\EC\relax} % signal + +\def\linetableEH + {\popmacro\EC + \popmacro\BC + \@EA\startlinetablehead\the\@@linetablehead\stoplinetablehead} + +\let\startlinetablebody\donothing +\let\stoplinetablebody \donothing + +\def\processlinetablebuffer + {\dosingleempty\doprocesslinetablebuffer} + +\def\doprocesslinetablebuffer[#1]% + {\bgroup + \let\startlinetable\donothing + \let\stoplinetable \donothing + \startlinetableanalysis\getbuffer[#1]\stoplinetableanalysis + \startlinetablerun \getbuffer[#1]\stoplinetablerun + \egroup} + +\def\processlinetablefile#1% + {\bgroup + \let\startlinetable\donothing + \let\stoplinetable \donothing + \startlinetableanalysis\readfile{#1}\donothing\donothing\stoplinetableanalysis + \startlinetablerun \readfile{#1}\donothing\donothing\stoplinetablerun + \egroup} + +\protect \endinput + +\doifnotmode{demo}{\endinput} + +\setuplinetable[n=6,m={2,2,2},lines=25] % m ? + +\setuplinetable[c][1] [width=2cm,background=color,backgroundcolor=red] +\setuplinetable[c][4] [width=3cm,background=color,backgroundcolor=yellow] +\setuplinetable[c][6] [width=3cm,background=color,backgroundcolor=magenta] +\setuplinetable[r][odd] [background=color,backgroundcolor=gray] +\setuplinetable[r][even][background=color,backgroundcolor=green] + +\starttext + +\showframe \showstruts + +\setupcolors[state=start] + +\setuppagenumbering[alternative=doublesided]\page[left] + +\startlinetable +\NC aaa\crlf aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR +\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR} +\stoplinetable + +\startlinetable +\NC[style=slanted,color=green,background=color,backgroundcolor=darkred,nx=2,uitlijnen=middle] xxx + \NC yy \NC ddddd \NC eeee \NC ff \NC \NR +\dorecurse{100}{\NC aaa \NC bb \NC c \NC ddddd \NC eeee \NC ff \NC \NR} +\stoplinetable + +% \startbuffer[lt] +% \NC aaa\crlf aaa \NC bb \NC c \NC ddddd \NC ee \NC ff \NC \NR +% \NC aaa\crlf aaa \NC b \NC cc \NC ddd \NC eeee \NC f \NC \NR +% \stopbuffer +% +% \processlinetablebuffer[lt] + +\stoptext diff --git a/tex/context/base/tabl-ntb.mkii b/tex/context/base/tabl-ntb.mkii new file mode 100644 index 000000000..1f9a9d574 --- /dev/null +++ b/tex/context/base/tabl-ntb.mkii @@ -0,0 +1,1584 @@ +%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 However, the next alternative also takes care of preceding +%D and following white space. + +% \def\bTBLCELL % why not \doinhibitblank +% {\inhibitblank\doconvertfont\tbltblstyle\empty\everypar{\delayedbegstrut}} + +% \def\eTBLCELL +% {\ifhmode +% \delayedendstrut +% \par % added 13/4/2006 +% \else +% \par +% \ifdim\prevdepth<\zeropoint % =-1000pt ? +% \vskip-\strutdp +% \else +% \removebottomthings +% \fi +% \fi} + +%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% +% {\setxvalue{\@@tblprefix#1:#2:l}{\TBLlevel}% +% \long\setvalue{\@@tblprefix#1:#2:t}% +% {\doifdefined{\@@tblprefix#1:#2:l} +% {\edef\TBLlevel{\getvalue{\@@tblprefix#1:#2:l}}}% +% #3}} + +\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} + +\presetlocalframed[\@@tbl\@@tbl] + +\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 + % 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\setTABLEparameters[\c!y\number\maximumrow][#1]\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 + \expanded{\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{\expanded{\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=]% + \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 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} +\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 + \expanded{\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 + \expanded{\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}} + +\setupTABLE + [\c!frameoffset=.5\linewidth, + \c!backgroundoffset=\v!frame, + \c!framecolor=\s!black, + \c!color=, + \c!style=, + \c!headstyle=\v!bold, + \c!headcolor=, + \c!strut=\v!yes, + \c!autostrut=\v!no, + \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-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 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/tabl-tab.tex b/tex/context/base/tabl-tab.tex new file mode 100644 index 000000000..361369ea2 --- /dev/null +++ b/tex/context/base/tabl-tab.tex @@ -0,0 +1,2507 @@ +%D \module +%D [ file=core-tab, +%D version=1997.10.10, +%D title=\CONTEXT\ Table Macros, +%D subtitle=\TABLE\ Embedding, +%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 Table Macros / TaBlE Embedding} + +% By now it makes more sense to merge the patches into the original +% and clean that one up too. + +% Don't change the splitter: +% +% ... \NR +% \TABLEnoalign{\page}\TABLEhead +% \NC ... + +% e-tex: reverse rows or vadjust or ... in tables +% \ifalign +% \xhrule : calls for 'special' with width +% BUG: +% +% \starttable[|l|l|] +% \HL +% \RL\FR \VL Head 1 \VL Head 2 \VL\FR +% \RL\LR \VL Head A \VL Head B \VL\LR % niet grijs ?? +% \HL +% \VL 1 \VL 2 \VL\FR +% \VL a \VL b \VL\LR +% \HL +% \stoptable + +% melden als in kleur conflict, uitgestelde test op \SR\SR + +% verengelsen +% interface + +% footnotes flushen +% \......TABLE........ namen +% kolommen testen +% unbreakable kop definieren +% voetnoten +% meldingen +% als direct \use{max} dan fout +% \BREAKPOINT +% breedte lijn telt +% errors: ook gray in handle + +% \AR -> als in DL dan \DR + +% nieuw: +% +% \NL / \NL[blanko] is skip, nog default? +% geen \HL in a row +% \HL[n] +% \VL[n] + remembers +% c{colorspec} key +% \HC[color][width] +% \VC[color] +% meldingen row, column, use, advise +% \AR: UITSTELLEN / EXPERIMENTEEL + +% WAARDELOZE ERROR HANDLER +% THIS RENEWED MODULE WORKS OK BUT STILL LOOKS BAD + +%D We felt no need to write our own table building macros, +%D simply because Michael Wichura made a terrific one. This +%D package is quite complete and well documented. In \CONTEXT\ +%D we provide a shell for consistent spacing as well as color +%D support. Implementing these features without adapting the +%D original macros is not trivial. One easilly gets conflicts +%D with \type{\omit}, \type{\span} and \type{\noalign}, which +%D means that we end up postponing and overloading macros, +%D mostly global. Now, let's start with loading the main +%D macros: + +\doifundefined{BeginTable}{\doinputonce{table.tex}} + +\unprotect + +%D \macros +%D {inintable, ifsplittables} +%D +%D First we declare some variables. These show a bit what we +%D are dealing with. First we introdoce some booleans that +%D enable us, inside as well as outside this module, to +%D determine in what mode we are. + +\newif\ifintable +\newif\ifsplittables + +%D \macros +%D {tracetablestrue} +%D +%D When I documented this module, I felt the need for tracing +%D options. After implementing this feature, I also added +%D warnings, error recovery and automatic spacing. + +\newif\iftracetables + +%D We show this feature in an eample that also shows some of +%D the basic table typesetting commands. +%D +%D \startbuffer +%D \starttable[|||] +%D \HL +%D \VL first \VL second \VL\AR +%D \HL +%D \VL alfa \VL 1 \VL\AR +%D \VL beta \VL 2 \VL\AR +%D \VL gamma \VL 3 \VL\AR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \startcombination +%D {\tracetablesfalse\getbuffer} {\type{\tracetablesfalse}} +%D {\tracetablestrue\getbuffer} {\type{\tracetablestrue}} +%D \stopcombination +%D +%D This table is specified as: +%D +%D \typebuffer +%D +%D This examples shows about the minimum of commands needed to +%D typeset such a table. In this table, the \type {\AR} is +%D automatically translated into the more primitive (but more +%D verbose) commands \type {\SR}, \type {\FR}, \type {\MR} and +%D \type {\LR} commands. +%D +%D \startbuffer +%D \starttables[|||] +%D \HL +%D \VL first \VL second \VL\AR +%D \HL +%D \VL alfa \VL 1 \VL\AR +%D \VL beta \VL 2 \VL\AR +%D \VL gamma \VL 3 \VL\AR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D When we use the split table feature, we get a bit more +%D information. +%D +%D {\tracetablesfalse\getbuffer} +%D +%D Sometimes in tables information shows up that is not typed +%D in by the user. These messages give a cue in what aspect a +%D table definition is wrong. +%D +%D \startbuffer +%D \starttable[||||] +%D \HL +%D \VL first second \VL third \VL\AR +%D \HL +%D \VL alfa \VL 1 \VL a \VL\AR +%D \VL beta \VL 2 \VL b \VL +%D \VL gamma \VL \THREE{3} c \VL\AR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \typebuffer +%D +%D Those terrible table has three errors, which all show up in +%D typeset messages. Errors cannot always recovered 100\% and +%D therefore can result in two or more succesive messages, like +%D in the last row. +%D +%D \getbuffer + +%D Bringing color into tables is complicated by the mere fact +%D that color is not part of \TEX. The main complication is +%D that we don't know in advance how wide a column will be. I +%D implemented color support in tables in the early 90's +%D because I needed it for some articles on color. I have to +%D admit that I seldom use the mechanism. +%D +%D Most color support in \CONTEXT\ makes use of colored rules. +%D At first sight, one is tempted to implement colors in tables +%D in a similar way, but as said, we don't know the dimensions +%D in advance. It turns out however that we don't have to, +%D simply because alignments take care of stretching rules to +%D the appropritate dimensions. This means that we can provide +%D backgrounds by coloring rules with the height of a row, +%D skipping upwards and finally drawing the content, like in: +%D +%D \gdef\ShowExample +%D {\startfiguretext +%D {none} +%D {\getbuffer} +%D \typebuffer +%D \stopfiguretext} +%D +%D \startbuffer +%D \starttable[|c|c|] +%D \HL +%D \BL[2] \SR +%D \VL test \VL test \VL\SR +%D \HL +%D \VL test \VL test \VL\FR +%D \VL test \VL test \VL\MR +%D \VL test \VL test \VL\LR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D Just to be complete we show how the other columns can be +%D given a background. Later we will provide more details over +%D the commands used. +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \HL +%D \BL[3] \SR +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \HL +%D \BC \BL[2] \SR +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \HL +%D \BC \BC \BL \SR +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \HL +%D \BC \BL \SR +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \BL \BL \SR +%D \HL +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample + +%D In these examples we can clearly see that for being a real +%D background, the color or gray specification has to precede +%D the content. Just to keep things simple, we can recall this +%D specification later on: +%D +%D \startbuffer +%D \starttable[|c|c|c|] +%D \BC \BL \SR +%D \HL +%D \VL test \VL test \VL test \VL\SR +%D \HL +%D \BR\FR +%D \VL test \VL test \VL test \VL\FR +%D \BR\MR +%D \VL test \VL test \VL test \VL\MR +%D \BR\LR +%D \VL test \VL test \VL test \VL\LR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D Close study learns that we can put the specification +%D before or after the \type{\HL}, whatever suits best. Keeping +%D track of these specifications is taken care of by the next +%D variables: + +\newif \ifTABLEgrayline % executing gray line +\newif \ifTABLEgraydone % gray line executed +\newtoks \TABLEgraytoks % gray line specification + +\newif\ifTABLEinbreak + +%D Nog vervangen: + +\def\c!Table{Table} +\def\m!TABLE{TABLE} + +%D We already saw that the table macros report errors and +%D provide automatic spacing. These features can only be +%D implemented by keeping track of the state, often the last +%D command on a row. + +\chardef\TABLEunknown = 0 + +\chardef\TABLEseparaterow = 1 +\chardef\TABLEfirstrow = 2 +\chardef\TABLEmidrow = 3 +\chardef\TABLElastrow = 4 +\chardef\TABLErule = 5 +\chardef\TABLEskip = 6 +\chardef\TABLEautorow = 7 + +\chardef\TABLEforcefirstrow = 1 +\chardef\TABLEforcelastrow = 2 + +\chardef\TABLEmissingrow = 1 +\chardef\TABLEmissingcolumn = 2 +\chardef\TABLEspanoverflow = 3 +\chardef\TABLEdivisionoverflow = 4 + +%D We store these states using efficient \type {\chardef}'s. +%D Like most variables, these are global ones. When needed, +%D especially when we flush the backgrounds, we can temporary +%D disable the assignment. + +\newif\ifsetTABLEaction + +\def\setTABLEaction#1% + {\ifsetTABLEaction\global\chardef\TABLEaction#1\fi} + +\def\setTABLEforce#1% + {\ifsetTABLEaction\global\chardef\TABLEforce#1\fi} + +\def\setTABLEerror#1% + {\global\chardef\TABLEerror#1} + +%D Before we come to using these variables, we redefine and/or +%D adapt some \TABLE\ macros. Within \TABLE's the \type{|} and +%D \type{"} have special meanings in templates and are active +%D during. Their meaning can therefore conflict with those +%D elsewhere defined. To be compatible with traditional \TABLE\ +%D as well as \CONTEXT's \type{||} and the active \type{"} +%D extensions for my german friends, we do some catcode magic. + +\newif\ifForgetTableBarAndQuote \ForgetTableBarAndQuotetrue + +% \bgroup + +% \catcode`\|=\@@active +% \catcode`\"=\@@active +% +% \gdef\pushouterbarandquote +% {\ifForgetTableBarAndQuote +% \ifnum\catcode`\|=\@@active \let\outertablebar |\else\let\outertablebar \relax\fi +% \ifnum\catcode`\"=\@@active \let\outertablequote"\else\let\outertablequote\relax\fi +% \let|\letterbar +% \let"\letterdoublequote +% \fi} +% +% \gdef\popouterbarandquote +% {\ifForgetTableBarAndQuote +% \ifx\outertablebar \relax\else\let|\outertablebar \fi +% \ifx\outertablequote\relax\else\let"\outertablequote\fi +% \else +% \redefinetablebarandquote +% \fi} +% +% \egroup +% +% \def\ObeyTableBarAndQuote +% {\ForgetTableBarAndQuotefalse +% \ifintable +% \redefinetablebarandquote +% \fi} + +\let\ActivateBarAndQuote \relax +\let\ObeyTableBarAndQuote\relax +\let\pushouterbarandquote\relax +\let\popouterbarandquote \relax + +%D \macros +%D {ObeyTableBarAndQuote} +%D +%D As said, the \type{|} and \type{"} active characters are +%D often used for other purposes. By default, the outside +%D meanings are therefore preserved and available inside +%D tables. If for some reason one wants to use the \TABLE\ +%D primitives, one can say: +%D +%D \starttyping +%D \ObeyTableBarAndQuote +%D \stoptyping +%D +%D To keep things verbose, as well as to show what \TABLE\ +%D commands we affect, we show some meanings. + +\def\normalTABLEshortrule {\!ttShortHrule} % \- +\def\normalTABLElongrule {\!ttLongHrule} % \= +\def\normalTABLEfullrule {\!ttFullHrule} % \_ +\def\normalTABLEendofrow {\!ttEndOfRow} % \\ +\def\normalTABLEsimplebar {\unskip\!ttRightGlue&&} % | +\def\normalTABLEcomplexbar {\unskip\!ttRightGlue&\omit\!ttAlternateVrule} % \| +\def\normalTABLEquote {\unskip\!ttRightGlue&\omit&} % " +\def\normalTABLElineformat {\normalTABLEendofrow+} +\def\normalTABLElineending {\normalTABLEendofrow0 } +\def\normalTABLEsinglerule {&\normalTABLElongrule&} +\def\normalTABLEmultirule#1{&\use{#1}\normalTABLElongrule&} + +%D The next hack is dedicated to Tobias, who found out that +%D paragraph entries don't break well. + +\def\TABLEhack{\hskip\zeropoint} + +%D The first attemp to solve this problem was: +%D +%D \starttyping +%D \def\normalTABLEquote% +%D {\unskip\TABLEhack\!ttRightGlue&\omit&\TABLEhack} +%D \stoptyping +%D +%D But, as usual, this interfered with \type {\omit}. +%D +%D The next attempt is redefining some core \TABLE\ macro:. +%D This works ok, but breaks for instance the~\type{b} +%D key handling. +%D +%D \starttyping +%D \def\!tfAdjoinPriorColumn% +%D {\ifnum\!taColumnNumber=0 +%D \!taPreamble=\!taRuleColumnTemplate +%D ... +%D \if!taOnceOnlyTabskip +%D \!thToksEdef\!taDataColumnTemplate= +%D {\TABLEhack####\TABLEhack\tabskip\the\!taLastRegularTabskip} +%D \else +%D \!taDataColumnTemplate{\TABLEhack##\TABLEhack}% +%D \fi +%D ... +%D \ReadFormatKeys} +%D \stoptyping + +% \newdimen\TABLEparheight + +\def\BeginTableParBox#1% + {\setbox\scratchbox\vtop\bgroup % \setbox added + \hsize#1\relax + \dontcomplain + \restoretablelineskips + \normalbaselines + \let~\!ttTie + \let\-\!ttDH + \blank[\v!disable]% % added + \the\EveryTableParBox} + +\def\EndTableParBox + {\removelastskip % itemize or so + \endgraf + \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 + \vtop to \noflines\lineheight{\box\scratchbox}% + \fi % esp between rows + \else % of paragraphs + \egroup + \fi +% \getboxheight\scratchdimen\of\box\scratchbox\relax% compensate for +% \ifdim\scratchdimen>\TABLEparheight % funny depth of +% \global\TABLEparheight\scratchdimen % multi-line box +% \fi % i.e. vtop + \box\scratchbox} + +% We also need to patch away the interfering math switch: + +% \mathpunctuationtrue + +% test, test +% \starttable[|c|] +% \NC1,,10\NC\AR +% \stoptable +% test, test + +\def\!ttBeginTableA[#1]{% + \if #1u% % "unboxed" table + \ifmmode + \def\!ttEndTable{% % user had better be in display math mode + \relax}% % and have only one table at the outer level + \else % user had better be in vertical mode + \bgroup + \def\!ttEndTable{% + \egroup}% + \fi + \else + %\hbox\bgroup $ + %\def\!ttEndTable{% + % \egroup % for the \vtop, \vbox, or \vcenter, yet to come + % $% for math mode + % \egroup}% for the \hbox + %\if #1t% + % \vtop + %\else + % \if #1b% + % \vbox + % \else + % \vcenter % math mode was essential for this + % \fi + %\fi + % + \hbox\bgroup + \def\!ttEndTable{\egroup\egroup}% + \if#1t% + \vtop + \else\if#1b% + \vbox + \else + \def\!ttEndTable{\egroup$\egroup}% + %$\vcenter + \scratchtoks\everymath\everymath\emptytoks$\everymath\scratchtoks\vcenter + \fi\fi + % + \bgroup % for the \vtop, \vbox, or \vcenter + \fi + \advance\!taRecursionLevel 1 % RecursionLevel governs initialization + \let\!ttRightGlue=\relax % This may be changed by \JustCenter, etc + \everycr\emptytoks % ={} + \ifnum \!taRecursionLevel=1 + \!ttInitializeTable + \fi} + +%D The next redefinition is more robust than the original: + +\def\SetTableToWidth#1% + {\doifelsenothing{#1}{\!taTableSpread\emptytoks}{\!taTableSpread{to #1}}} + +% (*) Try this one with \type {direction} and {girection}; +% the \PPCHTEX\ manual is a nice testcase. +% +% \startoverlay +% {\starttable[ | l w(2cm) | w(8cm) | ] +% \HL +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \MR +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \LR +% \HL +% \stoptable} +% {\starttable[ | l w(2cm) | p(8cm) | ] +% \HL +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \MR +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \LR +% \HL +% \stoptable} +% \stopoverlay +% \vskip2cm +% \starttable[ | l w(2cm) | p(8cm) | ] +% \HL +% \VL direction \VL \showbaselines \dorecurse{3}{direction }\VL \FR +% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \LR +% \HL +% \stoptable +% \vskip2cm +% \starttable[ | l w(2cm) | p(8cm) | ] +% \HL +% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \FR +% \VL direction \VL \showbaselines \dorecurse{8}{direction }\VL \LR +% \HL +% \stoptable + +%D To give an impression of what the (well documented) source +%D of \TABLE\ looks like, we first implement an alternative for +%D the numeric keys. The quantity keys (\type{q} and \type{Q}) +%D support the more european way of writing numbers: +%D +%D \startnarrower +%D 100.000.000,00 instead of 100,000,000.00 +%D \stopnarrower +%D +%D The next table shows how to use these keys. We use braces +%D instead of brackets because we need brackets to specify the +%D format. +%D +%D \startbuffer +%D \starttable{|q[00,000]|Q[00,00]|} +%D \HL +%D \VL -1,2 \VL 12,35 \VL\FR +%D \VL 11,203 \VL 2,4 \VL\LR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample +%D +%D Although a more efficient implementation is possible |<|we +%D can for instance share common macros|>| we just adapt a copy +%D of the numeric ones. To permit double loading of this +%D module, we check for the existence of one of the macros. + +\letvalue{!tk<\string q>}=\undefined +\letvalue{!tk<\string Q>}=\undefined + +%D We just copy the original {\em comments}. +%D +%D \em Key \type{q}: quantity item, non||math mode. + +\NewFormatKey q% + {\letempty\!tqStyle + \futurelet\!tnext\!tqTestForBracket} + +%D \em Key \type{Q}: quantity item, math mode. + +\NewFormatKey Q% + {\def\!tqStyle{$}% + \futurelet\!tnext\!tqTestForBracket} + +%D \em Note: the space between a quantity entry and the +%D following \type{|}, \type{"}, or \type{\|} is mandatory. +%D empty quantity entries are not allowed: use \type{{}} or +%D \type{\omit} instead. +%D +%D \em Test for bracket: invoked by the keys \type{q} and +%D \type{Q}. + +\def\!tqTestForBracket + {\ifx[\!tnext + \!thx\!tqGetArgument + \else + \!thx\!tqGetCode + \fi} + +%D \em Get code: e.g. \type{4}, or \type{4,0}, \type{0,4}, or +%D \type{10,2}. + +\def\!tqGetCode#1 % note the blank + {\!tqConvertCode #1,,!} + +%D \em Convert code: e.g. converts above to \type{[0000]}, +%D \type{[0000,]}, \type{[,0000]}, \type{[0000000000,00]}. + +\def\!tqConvertCode #1,#2,#3!% + {\begingroup + \aftergroup\edef + \aftergroup\!ttemp + \aftergroup{% + \aftergroup[% + \!taCountA #1 + \!thLoop + \ifnum \!taCountA>\zerocount + \advance\!taCountA \minusone + \aftergroup0 + \repeat + \def\!ttemp{#3}% + \ifx\!ttemp\empty + \else + \aftergroup, + \!taCountA #2 + \!thLoop + \ifnum\!taCountA>\zerocount + \advance\!taCountA \minusone + \aftergroup0 + \repeat + \fi + \aftergroup]\aftergroup}% + \endgroup\relax + \!thx\!tqGetArgument\!ttemp} + +%D \em Get argument: +%D +%D \starttyping +%D +%D \stoptyping + +\def\!tqGetArgument[#1]% + {\!tqMakeQuantityTemplate\!tqStyle#1,,!} + +%D \em Make quantity template. + +\def\!tqMakeQuantityTemplate#1#2,#3,#4!% #1= or $ + {\def\!ttemp{#4}% + \ifx\!ttemp\empty + \!taDimenC\zeropoint + \else + \setbox0\hbox{\mathsurround\zeropoint #1,#3#1}% + \!taDimenC\wd0 + \fi + \setbox0\hbox{\mathsurround\zeropoint #1#2#1}% + \!thToksEdef\!taDataColumnTemplate + ={\noexpand\!tqSetQuantityItem{\the\wd0 }{\the\!taDimenC}{#1}% + \the\!taDataColumnTemplate}% + \ReadFormatKeys} + +%D \em Set numeric item. + +\def\!tqSetQuantityItem #1#2#3#4 % + {\!tqSetQuantityItemA{#1}{#2}{#3}#4,,!} + +\def\!tqSetQuantityItemA #1#2#3#4,#5,#6!% + {\def\!ttemp{#6}% + \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}. + +% %D We also (have to) define a key for \type{\cap}: +% +% \letvalue{!tk<\string K>}=\undefined +% +% \NewFormatKey K% +% {\ReadFormatKeys b\smallcapped} + +%D A few pages back we saw backgrounds, further on we will see +%D colored rules, and here we provide a means to color the +%D entries in a column. (We can of course always use the normal +%D color commands for individual entries.) We could not use the +%D lowercase~\type{c}, because that one is used to force {\em +%D centering}. +%D +%D \startbuffer +%D \starttable[|C{red}|C{green}|C{blue}|] +%D \VL R(ed) \VL G(reen) \VL B(lue) \VL\SR +%D \stoptable +%D \stopbuffer +%D +%D \ShowExample + +\letvalue{!tk<\string C>}=\undefined + +\NewFormatKey C#1% + {\ReadFormatKeys b{\localstartcolor[#1]} a{\localstopcolor}} + +%D So now we have three new keys: +%D +%D \starttable[|||] +%D \HL +%D \NC \bf key \NC \bf meaning \NC\AR +%D \HL +%D \NC Q[x,y] \NC math mode formatted numbers \NC\AR +%D \NC q[x,y] \NC text mode formatted numbers \NC\AR +%D \NC C{identifier} \NC column entry color \NC\AR +%D \HL +%D \stoptable + +%D To be compatible with the tabulate environment, we also +%D support the \type {l}, \type {c} and \type {r} keys for +%D paragraph entries. + +\letvalue{!tk<\string l>}=\undefined +\letvalue{!tk<\string c>}=\undefined +\letvalue{!tk<\string r>}=\undefined +\letvalue{!tk<\string x>}=\undefined % not that needed + +\NewFormatKey c% + {\prependtoks\raggedcenter\to\!taDataColumnTemplate + \ReadFormatKeys \LeftGlue\hfil \RightGlue\hfil} + +\NewFormatKey l% + {\prependtoks\raggedright\to\!taDataColumnTemplate + \ReadFormatKeys \LeftGlue\empty \RightGlue\hfil} + +\NewFormatKey r% + {\prependtoks\raggedleft\to\!taDataColumnTemplate + \ReadFormatKeys \LeftGlue\hfil \RightGlue\empty} + +\NewFormatKey x% + {\prependtoks\notragged\to\!taDataColumnTemplate + \ReadFormatKeys \LeftGlue\hfil \RightGlue\empty} + +\appendtoks \TABLEparalignment \to \EveryTableParBox + +\def\!tfReFormat#1% + {\the \!taLeftGlue + \vbox{\forgetall\ialign{\span\the\!taDataColumnTemplate\cr#1\cr}}% + \the \!taRightGlue + \kern\zeropoint} % prevents \unskip / really needed + +%D Later on, we're going to implement multiple page table +%D support, therefore the next \TABLE\ macro needs to be +%D slightly adapted, i.c. the penalty is removed. We also +%D add basic color support. + +\def\!ttFullHruleA + {\!ttGetHalfRuleThickness + \startglobalTABLEcolor % added + \hrule\!thHeight\dimen0\!thDepth\dimen0 + \stopglobalTABLEcolor % added + %\penalty0 % removed + \egroup} + +%D We'll see that when we want to give a vertical rule a color, +%D we have to set and reset states. After heavy testing it +%D proved most useful to extend a \TABLE\ primitive with some +%D hooks. One thing to keep in mind is that \type{&} keeps +%D assignments local. Again, we add basic color support. + +\let\TABLEbeforebar\empty +\let\TABLEafterbar \empty + +\def\@VLn{1} +\def\@VLd{.125em} + +\def\do!ttInsertVrule % will be merged in 2005 + {\vrule \!thWidth + \ifnum\!tgCode=\plusone + \ifx\!tgValue\empty + \LineThicknessFactor + \else + \!tgValue + \fi + \LineThicknessUnit + \else + \!tgValue + \fi + \hskip\@VLd} + +\def\!ttInsertVrule + {\hfil + \TABLEbeforebar % added + \startglobalTABLEcolor % added + % we could do without this speedup, some day merge 'm + \ifcase\@VLn\or + \do!ttInsertVrule + \unskip + \else + \dorecurse\@VLn\do!ttInsertVrule + \gdef\@VLn{1}% + \unskip + \fi + \stopglobalTABLEcolor % added + \TABLEafterbar % added + \hfil + &} + +%D The next two macros are only adapted to basis rule +%D color support. + +\def\!tfSetVrule + {\!thToksEdef\!taRuleColumnTemplate= + {\noexpand\hfil + \noexpand\startglobalTABLEcolor % added + \noexpand\vrule + \noexpand\!thWidth + \ifnum\!tgCode=\plusone + \ifx\!tgValue\empty + \the\LineThicknessFactor + \else + \!tgValue + \fi + \!taLTU + \else + \!tgValue + \fi + ####% + \noexpand\hfil + \noexpand\stopglobalTABLEcolor % added + \the\!taRuleColumnTemplate}% + \!tfAdjoinPriorColumn} + +\def\!ttShortHruleA + {\!ttGetHalfRuleThickness + \startglobalTABLEcolor % added + \leaders\hrule\!thHeight\dimen0\!thDepth\dimen0\hfill + \stopglobalTABLEcolor % added + \null + \ignorespaces} + +%D We already showed the next one, but here we slightly adapt +%D the macro by adding an \type{\expandafter}. The space after +%D \type{#1} is crucial! + +\def\normalTABLEcomplexbar#1% + {\unskip\!ttRightGlue&\omit\expandafter\!ttAlternateVrule#1 } + +%D To get rid of interfering \type{\omit}'s when we are +%D checking the number of columns and reporting problems. The +%D extensions concern the second level check, the first +%D subbranch and advancing the column. + +\ifx\mscount\undefined \newcount\mscount \fi + +\def\!ttuse#1% + {\ifnum#1>\plusone + \omit + \global\TABLEdivisionfalse + \scratchcounter\currentTABLEcolumn % added + \advance\scratchcounter #1% % added + \advance\scratchcounter \minusone % added + \ifnum\scratchcounter>\maxTABLEcolumn % added + \def\next % added + {\setTABLEerror\TABLEspanoverflow % added + \handleTABLEerror}% % added + \else % added + \def\next % added + {\global\advance\currentTABLEcolumn #1% % added + \global\advance\currentTABLEcolumn \minusone % added + \mscount#1% \mscount is in Plain + \advance\mscount \minusone + \advance\mscount \mscount + \!thLoop + \ifnum\mscount>\plusone + \spanomit \advance\mscount\minusone + \repeat + \span}% + \fi % added + \else % added + \def\next % conflicts with possible next \omit % added + {\global\advance\currentTABLEcolumn \plusone}% % added + \fi + \next} % added + +% \starttable[|c|c|c|c|] +% \HL +% \VL {test} \VL \TWO{} \VL test \VL\FR +% \DL \DC \DL\DR +% \VL {test} \VL \TWO{} \VL test \VL\LR +% \HL +% \stoptable + +%D All commands that are executed between rows are to be put in +%D \type {\noalign}. We can however not verify if we (that is +%D \TABLE) does or did not enter this mode. A moderate dirty +%D but useful trick is using our own alternative:\footnote{Once +%D one has entered the stage of redefining \TEX\ primitives, +%D such hacks become a second nature. However, redefining \type +%D {\omit} and \type{\span} is not that easy.} + +\def\TABLEnoalign + {\noalign\bgroup\let\noalign\relax\let\next=} + +%D \macros +%D {starttable} +%D +%D The rest of this module is not easy to comprehend, mainly +%D because we have to take care of: +%D +%D \startitemize[packed] +%D \item \type{\startitemize[template]} +%D \item \type{\startitemize{template}} +%D \item \type{\startitemize[predefined]} +%D \stopitemize +%D +%D as well as: +%D +%D \startitemize[continue] +%D \item restart after table break +%D \stopitemize +%D +%D The official specification of the start command is: +%D +%D \showsetup{starttable} + +\newconditional\tablerepeathead +\newconditional\tablerepeattail + +\def\starttable + {\bgroup + \doif\@@tisplit\v!auto + {\ifinsidesplitfloat\let\@@tisplit\v!yes\fi}% + \doifinsetelse\@@tisplit{\v!yes,\v!repeat} + {\def\stoptable{\stoptables\egroup}% + \starttables} + {\doifelsenothing\@@tiframe + {\ifinsidefloat\else\startbaselinecorrection\fi} + {\startframedcontent[\@@tiframe]}% + \postponenotes + \firststagestartTABLE}} + +\def\stoptable + {\chuckTABLEautorow % before the tail, else noalign problem + \insertTABLEtail + \TABLEnoalign{\globalletempty\@@TABLEhead}% + \TABLEnoalign{\globalletempty\@@TABLEtail}% + \finishTABLE + \doifelsenothing\@@tiframe + {\ifinsidefloat\else + \stopbaselinecorrection + \goodbreak % compensates all the nobreaks + \fi} + \stopframedcontent + \egroup} + +%D Before we can grab the argument, we have to make sure that +%D the \CATCODES\ are set. The first stage takes care of that. + +\def\firststagestartTABLE + {\bgroup % kan-ie weg? + \global\intabletrue + \pushouterbarandquote + %catcode`\|=\@@other + \complexorsimple\secondstagestartTABLE} + +\def\simplesecondstagestartTABLE#1% + {\complexsecondstagestartTABLE[{#1}]} + +%D \macros +%D {definetabletemplate} +%D +%D The complex (and main) start macro first takes care of the +%D predefined case. Such a predefined setup looks like: +%D +%D \starttyping +%D \definetabletemplate[test][|||] +%D +%D \starttable[test] +%D \VL test \VL test \VL\AR +%D \VL test \VL test \VL\AR +%D \VL test \VL test \VL\AR +%D \stoptable +%D \stoptyping +%D +%D The implementation of the definition macro is not that +%D complicated: + +\def\definetabletemplate % to be redone + {\bgroup + \catcode`\|=\@@other + \doquadrupleempty\dodefinetabletemplate} + +\def\dodefinetabletemplate[#1][#2][#3][#4]% + {\ifsecondargument + \setgvalue{\c!Table#1}{\douseTABLEtemplate{#2}{#3}{#4}}% + \fi + \egroup} + +\def\douseTABLEtemplate#1#2#3% + {\gdef\TABLEhead{\getvalue{@@TABLEhead#2}}% + \gdef\TABLEtail{\getvalue{@@TABLEtail#3}}% + \complexsecondstagestartTABLE[#1]} + +%D The optional third and fourth arguments define which table +%D head and tail to use. +%D +%D \starttyping +%D \definetabletemplate[test][|||][before][after] +%D \stoptyping +%D +%D This also means that one can define table heads and tails +%D by name! +%D +%D \starttyping +%D \starttablehead[before] +%D \HL \VL first \VL second \VL \SR \HL +%D \stoptablehead +%D \stoptyping +%D +%D Templates defined this way get protected names, that cannot +%D conflict with existing commands. +%D +%D \showsetup{definetabletemplate} +%D +%D The second half of the next macro prepares table +%D splitting. + +\def\insertTABLEhead + {\TABLEnoalign{\global\settrue \preventTABLEbreak \global\setfalse\someTABLEhead}% + \TABLEhead + \TABLEnoalign{\global\setfalse\preventTABLEbreak}} + +\def\insertTABLEtail + {\TABLEnoalign{\global\settrue \preventTABLEbreak \global\setfalse\someTABLEtail}% + \TABLEtail + \TABLEnoalign{\global\setfalse\preventTABLEbreak}} + +% \def\dorestartTABLE#1% +% {\gdef\restartTABLE{#1}% +% \restartTABLE +% \insertTABLEhead +% \ifsplittables \ifconditional \tablerepeattail +% \TABLEnoalign{\goodbreak}% +% \insertTABLEtail +% \TABLEnoalign{\goodbreak}% +% \fi \fi} + +\def\verysimpleTableHL + {\TABLEnoalign{\expandafter\normalTABLEfullrule\@@tiHLheight}} + +\def\dorestartTABLE#1% + {\gdef\restartTABLE{#1}% + \restartTABLE + \TABLEnoalign{\globalpushmacro\simpleTableHL\global\let\simpleTableHL\verysimpleTableHL}% + \insertTABLEhead + \ifsplittables \ifconditional \tablerepeattail + \TABLEnoalign{\goodbreak}% + \insertTABLEtail + \TABLEnoalign{\goodbreak}% + \fi \fi + \TABLEnoalign{\globalpopmacro\simpleTableHL}} + +\bgroup \catcode`|=\@@other \catcode`"=\@@other + +\gdef\complexsecondstagestartTABLE#1[#2]% brr nested mess + {\bgroup + \@@useotherbar + \@@useotherquote + \global\setfalse\someTABLEhead + \global\setfalse\someTABLEtail + \expanded{\doifinstringelse{|}{#2}} + {\xdef\restartTABLE{\noexpand\dorestartTABLE{\noexpand\thirdstagestartTABLE{#2}}}} + {\doifdefinedelse{\c!Table#2} + {\gdef\restartTABLE{\getvalue{\c!Table#2}}} + {\gdef\restartTABLE{\dorestartTABLE{\getvalue{#2}}}}}% + \egroup + \restartTABLE} + +\egroup + +%D The third stage involves a lot of (re)sets, which we will +%D explain later. + +%D The next definition is convenient and more in tune with +%D \CONTEXT. + +\let \everytable \EveryTable + +%D We immediately use this register: + +\appendtoks + \fixedspaces + \let\_\normalunderscore +\to \everytable + +%D Now we can start the table. + +\def\thirdstagestartTABLE#1% + {\global\setTABLEactiontrue + \setTABLEaction\TABLEunknown + \setTABLEforce\TABLEunknown + \setTABLEerror\TABLEunknown + \global\TABLEgraylinefalse + \global\TABLEgraydonefalse + \globalletempty\TABLEgrayline + \globalletempty\nextTABLEgrayline + \globalletempty\TABLEgraylineerror + \globalletempty\TABLEgraylinestatus + \resetVLvalues + \appendtoks\popouterbarandquote\to\EveryTable + \appendtoks\localTABLEsetup\to\EveryTable + \BeginTable[\ifsplittables u\else b\fi]% + \defineTABLEunits + \defineTABLEsteps + \defineTABLErules + \defineTABLEdivisions + \defineTABLEshorthands + \defineTABLEbackgrounds + \defineTABLEendings + \forgetall % added + \doifsomething{#1} + {\def\TABLEformat{#1}% + \getTABLEnofcolumns\TABLEformat + % more modern is to use catcode tables + \expandafter\BeginFormat\TABLEformat\EndFormat}} + +\def\finishTABLE + {\chuckTABLEautorow + \unskip\crcr + \EndTable + \global\intablefalse + \egroup} + +%D \macros +%D {starttables} +%D +%D Split tables are specified using the plural form of the +%D start and stop commands. +%D +%D \showsetup{starttables} +%D +%D For example: +%D +%D \starttyping +%D \starttables[|||] +%D \HL +%D \VL element \VL atom weight \VL\AR +%D \HL +%D \VL ....... \VL ........... \VL\AR +%D \VL ....... \VL ........... \VL\AR +%D \HL +%D \stoptables +%D \stoptyping + +\newbox\tablecontentbox + +\def\starttables + {\bgroup + \splittablestrue + \doifelse\@@tisplit\v!repeat + {\settrue \tablerepeathead\settrue \tablerepeattail} + {\setfalse\tablerepeathead\setfalse\tablerepeattail}% + \flushnotes + \setbox\tablecontentbox\vbox\bgroup + \forgetall + \global\TABLEinbreakfalse + \firststagestartTABLE} + +% \def\stoptables +% {\ifconditional\tablerepeattail\else\insertTABLEtail\fi +% \finishTABLE +% \egroup +% \dosplittablebox\tablecontentbox +% \flushnotes +% \egroup} + +\def\stoptables + {\chuckTABLEautorow % AM: before the tail, else noalign problem + \ifconditional\tablerepeattail\else\insertTABLEtail\fi + \finishTABLE + \egroup +\dontcomplain + \dosplittablebox\tablecontentbox + \flushnotes + \egroup} + +\newdimen\TABLEcaptionheight % obsolete + +\def\dosplittablebox#1% + {\resettsplit + \def\tsplitminimumfreelines{2}% + \def\tsplitminimumfreespace{\TABLEcaptionheight}% + \setbox\tsplitcontent\box#1% + \ifconditional\tablerepeathead \ifconditional\someTABLEhead + \setbox\tsplithead\vsplit\tsplitcontent to \lineheight + \setbox\tsplithead\vbox{\unvbox\tsplithead}% + \fi \fi + \ifconditional\tablerepeattail \ifconditional\someTABLEtail + \setbox\tsplittail\vsplit\tsplitcontent to \lineheight + \setbox\tsplittail\vbox{\unvbox\tsplittail}% + \fi \fi + \ifinsidefloat\else + \def\tsplitbeforeresult{\startbaselinecorrection}% + \def\tsplitafterresult {\stopbaselinecorrection}% + \fi + \handletsplit} + +%D When the table in the previous example is split across +%D pages, only the first gets a head. We could have said +%D something like: +%D +%D \starttyping +%D \starttablekop +%D \HL +%D \VL element \VL atom weight \VL\AR +%D \HL +%D \stoptablekop +%D +%D \starttablestaart +%D \HL +%D \stoptablestaart +%D +%D \starttables[|||] +%D \VL ....... \VL ........... \VL\AR +%D \VL ....... \VL ........... \VL\AR +%D \stoptables +%D \stoptyping +%D +%D This time each split table gets a head line and ends with +%D a rule. Keep in mind that such heads also apply to the +%D unbroken ones and should be defined local (grouped) if +%D needed. The rather complicated definition below is due to +%D the fact that the stopcondition is interface language +%D dependant. + +\let\@@TABLEhead\empty \def\TABLEhead{\@@TABLEhead} +\let\@@TABLEtail\empty \def\TABLEtail{\@@TABLEtail} + +\letvalue{\e!start\v!tablehead}=\undefined +\letvalue{\e!stop \v!tablehead}=\undefined +\letvalue{\e!start\v!tabletail}=\undefined +\letvalue{\e!stop \v!tabletail}=\undefined + +\expanded + {\def\csname\e!start\v!tablehead\endcsname##1\csname\e!stop\v!tablehead\endcsname% + {\noexpand\setTABLEhead##1\noexpand\end}} + +\expanded + {\def\csname\e!start\v!tabletail\endcsname##1\csname\e!stop\v!tabletail\endcsname% + {\noexpand\setTABLEtail##1\noexpand\end}} + +%D The second argument is a dummy one, by scanning for it, we +%D get rid of interfering spaces. + +\def\setTABLEhead{\dodoubleempty\dosetTABLEhead} +\def\setTABLEtail{\dodoubleempty\dosetTABLEtail} + +\newconditional\preventTABLEbreak +\newconditional\someTABLEhead + +\def\dosetTABLEhead[#1][#2]#3\end{\setvalue{@@TABLEhead#1}{\TABLEnoalign{\global\settrue\someTABLEhead}#3}} +\def\dosetTABLEtail[#1][#2]#3\end{\setvalue{@@TABLEtail#1}{\TABLEnoalign{\global\settrue\someTABLEtail}#3}} + +%D Redudant \type{\HL}'s are removed automatically, so +%D mid||lines can be used without problems. + +%D We need an alternative for the normal complex or simple +%D commands, because assignments in these system commands +%D conflict with \type{\noalign}. This alternative is about +%D as efficient as possible. + +\def\complexorsimpleTable#1#2% + {\csname\if[\noexpand#2\s!complex\else\s!simple\fi\c!Table#1\endcsname#2} + +%D The next one is used in \type{\VL} cum suis and honours +%D the next grouping. + +\def\docomplexorsimpleTable#1#2% + {\ifx\next\bgroup\@EA#2\else\@EA\dodocomplexorsimpleTable\@EA#1\@EA#2\fi} + +\def\dodocomplexorsimpleTable#1#2#3% + {\if[\noexpand#3\@EA#1\else\@EA#2\fi#3} + +%D The order of the next macros is more or less random. First +%D we implement error recovery. Errors are reported to the +%D screen and log file as well as visualized in the table in +%D teletype. + +\def\handleTABLEerror + {\ifTABLEgrayline \else + \ifnum\TABLEerror=\TABLEunknown \else + \setTABLEaction\TABLEunknown + \globalletempty\checkTABLEautorow + \globalletempty\chuckTABLEautorow + \fi + \ifcase\TABLEerror + % no error + \or + % \TABLEmissingrow + \tttf [missing row]% + \writestatus\m!TABLE{missing row}% + \SR + \or + % \TABLEmissingcolumn + \fillTABLEcolumns + \tttf [missing column]% + \writestatus\m!TABLE{missing column}% + \SR + \or + % \TABLEspanoverflow + \fillTABLEcolumns + \tttf [columnspan too large]% + \writestatus\m!TABLE{columnspan too large}% + \SR + \or + % \TABLEdivisionoverflow + \fillTABLEcolumns + \tttf [division line too long]% + \writestatus\m!TABLE{division line too long}% + \SR + \fi + \fi + \ifnum\TABLEerror=\TABLEunknown \else + \finishTABLErow + \fi} + +\def\finishTABLErow + {\crcr + \TABLEnoalign + {\nobreak + \setTABLEaction\TABLEunknown + \setTABLEerror\TABLEunknown + \globalletempty\checkTABLEautorow + \globalletempty\chuckTABLEautorow + \global\currentTABLEcolumn\zerocount}} + +\def\fillTABLEcolumns + {\ifnum\currentTABLEcolumn>\maxTABLEcolumn \else + \global\advance\currentTABLEcolumn \plusone + \normalTABLEquote + \expandafter\fillTABLEcolumns + \fi} + +%D Next we enter the more complicated area of column and row +%D switching. I won't go into much detail from now on, but just +%D mention the general principles. +%D +%D \startitemize[3*ruim] +%D \sym{\type{\SR}} end a separate row (between rules) +%D \sym{\type{\FR}} end a first row (after a rule) +%D \sym{\type{\MR}} end a mid row (between text lines) +%D \sym{\type{\LR}} end a last row (before a rule) +%D \stopitemize +%D +%D and best of all: +%D +%D \startitemize[continue] +%D \sym{\type{\AR}} end a row with automatic spacing +%D \stopitemize +%D +%D As far as possible, we report confusing situations. In +%D most cases one can use \type{\AR}, which transfigurates +%D itself into one of the other types. +%D +%D \starttyping +%D \starttable[||] +%D \HL +%D \VL a separate row \VL\SR +%D \HL +%D \VL a first row \VL\FR +%D \VL a mid row \VL\MR +%D \VL a last row \VL\LR +%D \HL +%D \stoptable +%D \stoptyping +%D +%D In this example we could have used \type{\AR} without +%D problems. +%D +%D Color or gray scale backgrounds precede the content. They +%D are passed over horizontal (division) lines when needed. +%D Errors in the color template are traced elsewhere. Here we +%D only check for inconsistent spacing. Due to the way \TEX\ +%D handles alignments, we cannot automate spacing for colored +%D rows and columns. + +\chardef\TABLErowzero=0 + +\def\checkTABLErow#1% pure for message purposes + {\unskip % added + \ifTABLEgraydone + \defconvertedargument\asciia{#1}% + \defconvertedcommand \asciib\TABLEendBCL + \ifx\asciia\asciib \else + \writestatus\m!TABLE{confusing \asciia\space and \asciib}% + \gdef\TABLEgraylineerror% + {\globalletempty\TABLEgraylineerror + [\asciia\unskip<->\asciib\unskip]}% + \fi + \global\TABLEgraydonefalse + \fi} + +\def\defineTABLEendings + {\let\SR\TableSR + \let\FR\TableFR + \let\MR\TableMR + \let\LR\TableLR + \let\AR\TableAR} + +\def\TableSR + {\ifTABLEgrayline \else + \ifnum\TABLEaction=\TABLEfirstrow + \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% + \else\ifnum\TABLEaction=\TABLEmidrow + \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% + \else\ifnum\TABLEaction=\TABLEmidrow + \writestatus\m!TABLE{change \string\SR\space into \string\MR/\string\LR}% + \fi\fi\fi + \fi + \checkTABLErow\SR + \endTABLErow\TABLEseparaterow\TABLErowfactor\TABLErowfactor} + +\def\TableFR + {\ifTABLEgrayline \else + \ifnum\TABLEaction=\TABLEmidrow + \writestatus\m!TABLE{change \string\FR\space into \string\MR/\string\LR}% + \else\ifnum\TABLEaction=\TABLElastrow + \writestatus\m!TABLE{change \string\FR\space into \string\MR/\string\LR}% + \fi\fi + \fi + \checkTABLErow\FR + \endTABLErow\TABLEfirstrow\TABLErowfactor\TABLErowzero} + +\def\TableMR + {\ifTABLEgrayline \else + \ifnum\TABLEaction=\TABLErule + \writestatus\m!TABLE{change \string\MR\space into \string\FR/\string\SR}% + \else\ifnum\TABLEaction=\TABLElastrow + \writestatus\m!TABLE{change \string\MR\space into \string\FR}% + \fi\fi + \fi + \checkTABLErow\MR + \endTABLErow\TABLEmidrow00} + +\def\TableLR + {\ifTABLEgrayline \else + \ifnum\TABLEaction=\TABLErule + \writestatus\m!TABLE{change \string\LR\space into \string\FR/\string\SR}% + \fi + \fi + \checkTABLErow\LR + \endTABLErow\TABLElastrow\TABLErowzero\TABLErowfactor} + +%D \macros +%D {ifcheckTABLEcolums} +%D +%D +%D The next macros handle the actual row ending. This macro +%D also take care of space corrections due to table splitting +%D when \type{\MR} and collegues are used. When tracing is +%D enabled, the corrections as well as the values used to +%D determine the available space are shown (in color). By default +%D checking is off. + +\newif\ifcheckTABLEcolumns + +\let\beforeTABLEline\empty +\let\afterTABLEline \empty + +\def\doendTABLErow#1#2#3% + {\handleTABLEbreak#2#3% + \beforeTABLEline + \ifcase#1\relax + % unknown + \or + \endofTABLEline[blue][\SR->\SR]\TABLErowfactor\TABLErowfactor + \or + \endofTABLEline[red][\FR->\FR]\TABLErowfactor\TABLErowzero + \or + \ifnum\TABLEforce=\TABLEforcelastrow + \endofTABLEline[red][\MR->\LR]\TABLErowzero\TABLErowfactor + \else\ifnum\TABLEforce=\TABLEforcefirstrow + \endofTABLEline[red][\MR->\FR]\TABLErowfactor\TABLErowzero + \else + \endofTABLEline[green][\MR->\MR]\TABLErowzero\TABLErowzero + \fi\fi + \or + \endofTABLEline[red][\LR->\LR]\TABLErowzero\TABLErowfactor + \fi + \TABLEnoalign + {\setTABLEforce\TABLEunknown + \global\currentTABLEcolumn\zerocount}% + \afterTABLEline} + +\def\endTABLErow#1#2#3% + {\setTABLEaction#1% + \ifTABLEgrayline + \finishTABLErow + \else + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \doendTABLErow{#1}{#2}{#3}% + \else\ifcheckTABLEcolumns + \setTABLEerror\TABLEmissingcolumn + \handleTABLEerror + \else + \doendTABLErow{#1}{#2}{#3}% + \fi\fi + \fi} + +%D Handling \type{\AR} is postponed till the next row. The +%D check takes care of the first and mid rows, the chuck macro +%D |<|how about that name|>| handles the last row. + +\def\TableAR + {\ifTABLEgraydone + \globalletempty\checkTABLEautorow + \globalletempty\chuckTABLEautorow + \global\TABLEgraydonefalse + \TABLEendBCL + \else + \globallet\checkTABLEautorow\docheckTABLEautorow + \globallet\chuckTABLEautorow\dochuckTABLEautorow + \fi} + +\let\checkTABLEautorow\empty +\let\chuckTABLEautorow\empty + +\def\docheckTABLEautorow + {\globallet\checkTABLEautorow\empty + \ifnum\TABLEaction=\TABLErule \FR + \else\ifnum\TABLEaction=\TABLEunknown \FR + \else \MR + \fi\fi} + +\def\dochuckTABLEautorow + {\globalletempty\checkTABLEautorow + \globalletempty\chuckTABLEautorow + \ifnum\TABLEaction=\TABLErule \SR + \else\ifnum\TABLEaction=\TABLEunknown \SR + \else \LR + \fi\fi} + +%D When a table is split, we also add a tail and when present +%D we repeat the table head. + +\def\handleTABLEbreak#1#2% + {\globalletempty\beforeTABLEline + \gdef\afterTABLEline{\TABLEnoalign{\ifconditional\preventTABLEbreak\nobreak\else\goodbreak\fi}}} + +%D When tables are split, the spacing before and after a +%D horizontal rule is corrected according to what we expect. + +\def\endofTABLEline[#1][#2->#3]#4#5% + {\ifx#2#3\else + \writestatus\m!TABLE{\string#2\space changed into \string#3}% + \fi + \iftracetables + \bgroup + \tttf\space + \ifnum\TABLEerror=\TABLEunknown + \ifx#2#3\else\string#2->\fi + \else + ->% + \fi + \color[#1]{\string#3}% + \ifx\TABLEgraylineerror\empty + \space\TABLEgraylinestatus + \else + \space\TABLEgraylineerror + \fi + \egroup + \else\ifx\TABLEgraylineerror\empty \else + % \bgroup + % \tttf\space\TABLEgraylineerror + % \egroup + \fi\fi + \globalletempty\TABLEgraylinestatus + \globalletempty\TABLEgraylineerror + \expandafter\normalTABLElineformat#4#5\crcr % \crcr nodig ? + \TABLEnoalign{\nobreak\global\setTABLEactiontrue}} + +%D In order to prevent (as good as possible) alignment overflow +%D and therefore \TEX\ error messages, we check the maximum +%D number of columns. We keep track of the current column and +%D maximum column by means of two \COUNTERS. Keep in mind that +%D the number of \type{|}'s and \type{\VL}'s or alike is always +%D one more than the number of columns. + +\newcount\currentTABLEcolumn +\newcount\maxTABLEcolumn + +%D While defining this macro we change the \CATCODE\ of +%D \type{|}. When counting the bars, we use a non active +%D representation of the bar, simply because we cannot be sure +%D if the bar is active or not.\footnote{Normally it is, but +%D \TABLE\ changes the catcode when needed.} + +\bgroup + \catcode`\|=\@@other \gdef\@@otherbar {|} + \catcode`\"=\@@other \gdef\@@otherquote {"} + \catcode`\|=\@@active \gdef\@@useotherbar {\let|\@@otherbar} + \catcode`\"=\@@active \gdef\@@useotherquote{\let"\@@otherquote} +\egroup + +\bgroup \catcode`\|=\@@other + +\gdef\getTABLEnofcolumns#1% + {\bgroup + \cleanupfeatures % needed ! + \@@useotherbar + \@@useotherquote + \expanded{\defconvertedargument\noexpand\ascii{#1}}% + \@EA\doglobal\@EA\counttoken\@EA|\@EA\in\ascii\to\maxTABLEcolumn + \global\advance\maxTABLEcolumn \minusone + % in case of & counting, divide by 2 + \egroup} + +\egroup + +\def\!ttDoHalign + {\edef\restoretablelineskips + {\baselineskip \the\baselineskip + \lineskiplimit\the\lineskiplimit + \lineskip \the\lineskip + \tabskip \the\tabskip}% + \baselineskip \zeropoint + \lineskiplimit\zeropoint + \lineskip \zeropoint + \tabskip \zeropoint + % does not work in normal tex + % \expanded{\getTABLEnofcolumns{\the\!taPreamble}}% added + \halign \the\!taTableSpread \bgroup + \span\the\!taPreamble + \ifx \!tfRowOfWidths \empty \else \!tfRowOfWidths \cr \fi} + +%D \startitemize[3*ruim] +%D \sym{\type{\VL}} a vertical line +%D \sym{\type{\VC}} a vertical colored line +%D \sym{\type{\HL}} a horizontal line +%D \sym{\type{\HC}} a horizontal colored line +%D \stopitemize + +% \def\defineTABLErules +% {\let\VL\TableVL +% \let\VC\TableVC +% \let\HL\TableHL +% \let\HC\TableHC} + +\def\defineTABLErules + {\let\VL\TableVL + \let\VC\TableVC + \let\HL\TableHL + \let\HC\TableHC + \let\VS\TableVS + \let\VD\TableVD + \let\VT\TableVT + \let\VN\TableVN} + +\def\TableVL + {\checkTABLEautorow + \nextTABLEgrayline + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \setTABLEerror\TABLEmissingrow + \handleTABLEerror + \else + \global\advance\currentTABLEcolumn \plusone + \expandafter\doTableVL + \fi} + +\def\doTableVL + {\futurelet\next\dodoTableVL} + +\def\dodoTableVL + {\docomplexorsimpleTable\complexTableVL\simpleTableVL} + +\def\complexTableVL[#1]% + {\scratchcounter=0#1% + \multiply\scratchcounter \@@tiVLwidth + \setxvalue{wVL\the\currentTABLEcolumn}{\the\scratchcounter}% + \simpleTableVL} + +\def\simpleTableVL + {\doifundefined{wVL\the\currentTABLEcolumn}% + {\setgvalue{wVL\the\currentTABLEcolumn}{\@@tiVLwidth}}% + \gdef\TABLEbeforebar + {\getvalue{bVL\the\currentTABLEcolumn}% + \letgvalueempty{bVL\the\currentTABLEcolumn}}% + \gdef\TABLEafterbar + {\getvalue{eVL\the\currentTABLEcolumn}% + \letgvalueempty{eVL\the\currentTABLEcolumn}}% + \edef\@@tiVLwidth{\getvalue{wVL\the\currentTABLEcolumn}}% + \expanded{\normalTABLEcomplexbar\@@tiVLwidth\space}}% \relax breaks \use + +% \starttable[|||] +% \HL +% \VL test \VS test \VL \FR +% \VL test \VD test \VL \MR +% \VL test \VT test \VL \LR +% \HL +% \stoptable + +\def\TableVS {\VN1} +\def\TableVD {\VN2} +\def\TableVT {\VN3} +\def\TableVN#1{\gdef\@VLn{#1}\VL} + +\def\resetVLvalues + {\dostepwiserecurse\zerocount\maxTABLEcolumn\plusone + {\setgvalue{wVL\recurselevel}{\@@tiVLwidth}% + \letgvalueempty{bVL\recurselevel}% + \letgvalueempty{eVL\recurselevel}}% + \global\currentTABLEcolumn\zerocount} + +\def\TableVC + {\checkTABLEautorow + \nextTABLEgrayline + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \setTABLEerror\TABLEmissingrow + \handleTABLEerror + \else + \global\advance\currentTABLEcolumn \plusone + \expandafter\doTableVC + \fi} + +\def\doTableVC + {\futurelet\next\dodoTableVC} + +\def\dodoTableVC + {\docomplexorsimpleTable\complexTableVC\simpleTableVC} + +\def\complexTableVC[#1]% + {\global\setvalue{bVC\the\currentTABLEcolumn}{\localstartcolor[#1]}% + \global\setvalue{eVC\the\currentTABLEcolumn}{\localstopcolor}% + \simpleTableVC} + +\def\simpleTableVC + {\global\setvalue{bVL\the\currentTABLEcolumn}% + {\getvalue{bVC\the\currentTABLEcolumn}}% + \global\setvalue{eVL\the\currentTABLEcolumn}% + {\getvalue{eVC\the\currentTABLEcolumn}}% + \doTableVL} + +\def\TableHL + {\ifnum\currentTABLEcolumn>\maxTABLEcolumn + \chuckTABLEautorow + \else\ifnum\currentTABLEcolumn=\zerocount + %\chuckTABLEautorow + \TABLEnoalign + {\globalletempty\checkTABLEautorow + \globalletempty\chuckTABLEautorow}% + \else + \setTABLEerror\TABLEmissingcolumn + \handleTABLEerror + \fi\fi + \complexorsimpleTable{HL}} + +\def\complexTableHL[#1]% + {\TABLEnoalign + {\scratchcounter0#1% + \multiply\scratchcounter \@@tiHLheight + \edef\@@tiHLheight{\the\scratchcounter}% + \simpleTableHL}} + +\def\simpleTableHL + {\TABLEnoalign + {\nobreak + \ifnum\TABLEaction=\TABLErule + \writestatus\m!TABLE{skipping \string\HL}% \statusmessage + \else + \ifnum\TABLEaction=\TABLEmidrow + \writestatus\m!TABLE{change \string\MR\space into \string\LR/\string\SR}% + \else\ifnum\TABLEaction=\TABLEfirstrow + \writestatus\m!TABLE{change \string\MR\space into \string\SR}% + \fi\fi + \startHLcommand + \expandafter\normalTABLEfullrule\@@tiHLheight + \stopHLcommand + \globalletempty\startHLcommand + \globalletempty\stopHLcommand + \accountTABLElinewidth + \fi + \setTABLEaction\TABLErule + \nobreak}} + +\let\startHLcommand\empty +\let\stopHLcommand \empty + +\def\TableHC + {\complexorsimpleTable{HC}} + +\def\complexTableHC[#1]% + {\TABLEnoalign + {\gdef\startHCcommand{\localstartcolor[#1]}% + \gdef\stopHCcommand {\localstopcolor}}% + \simpleTableHC} + +\def\simpleTableHC + {\TABLEnoalign + {\globallet\startHLcommand\startHCcommand + \globallet\stopHLcommand \stopHCcommand}% + \HL} + +%D \startitemize[3*ruim] +%D \sym{\type{\NL}} a vertical skip +%D \sym{\type{\NR}} goto the next row +%D \sym{\type{\NC}} goto the next column +%D \sym{\type{\FC}} a first column +%D \sym{\type{\MC}} a mid column +%D \sym{\type{\LC}} a last column +%D \stopitemize + +% n+1 uitleggen + +\def\defineTABLEsteps + {\let\NL\TableNL + \let\NR\TableNR + \let\NC\TableNC + \let\FC\TableNC + \let\MC\TableNC + \let\LC\TableNC} + +\def\TableNL + {\complexorsimpleTable{NL}} + +\def\complexTableNL[#1]% + {\TABLEnoalign + {\edef\@@tiNL{#1}% + \simpleTableNL}}% + +\def\simpleTableNL + {\TABLEnoalign + {\nobreak + \setbox0\vbox{\blank[\@@tiNL]}% + \vskip\ht0 + \nobreak}} + +\def\TableNR + {\ifnum\currentTABLEcolumn>\maxTABLEcolumn + \global\currentTABLEcolumn\zerocount + \normalTABLElineending + \else + \setTABLEerror\TABLEmissingcolumn + \handleTABLEerror + \fi + \TABLEnoalign + {\nobreak + \setTABLEaction\TABLEunknown}} + +\def\TableNC + {\checkTABLEautorow + \nextTABLEgrayline + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \setTABLEerror\TABLEmissingrow + \handleTABLEerror + \else + \global\advance\currentTABLEcolumn \plusone + \normalTABLEquote + \fi} + +% \bgroup +% \catcode`\|=\@@active +% \catcode`\"=\@@active +% \gdef\redefinetablebarandquote +% {\def|{\VL}% % \normalTABLEsimplebar +% \def\|##1{\VL[##1]}% % \normalTABLEcomplexbar +% \def"{\NC}} % \normalTABLEquote +% \egroup + +\let\redefinetablebarandquote\relax + +%D \startitemize[3*ruim] +%D \sym{\type{\DL}} +%D \sym{\type{\DV}} (\type{\VD}) +%D \sym{\type{\DC}} +%D \sym{\type{\DR}} +%D \stopitemize + +\newif\ifTABLEdivision + +% \def\defineTABLEdivisions +% {\global\TABLEdivisionfalse % in start +% \let\DL\TableDL +% \let\DC\TableDC +% \let\DV\TableDV +% \let\VD\TableDV +% \let\DR\TableDR} + +\def\defineTABLEdivisions + {\global\TABLEdivisionfalse % in start + \let\DL\TableDL + \let\DC\TableDC + \let\DV\TableDV + \let\DR\TableDR} + +\def\checkTABLEdivision + {\ifTABLEdivision \else + \chuckTABLEautorow + \global\currentTABLEcolumn\zerocount + \global\TABLEdivisiontrue + \fi} + +\def\TableDL + {\checkTABLEdivision + \complexorsimpleTable{DL}} + +\def\simpleTableDL + {\complexTableDL[1]} + +\def\complexTableDL[#1]% + {\ifnum\TABLEaction=\TABLErule + \writestatus\m!TABLE{skipping \string\DL}% + \else + \ifnum\TABLEaction=\TABLEmidrow + \writestatus\m!TABLE{change \string\MR\space into \string\LR/\string\SR}% + \else\ifnum\TABLEaction=\TABLEfirstrow + \writestatus\m!TABLE{change \string\MR\space into \string\SR}% + \fi\fi + \setTABLEaction=\TABLEunknown + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \setTABLEerror\TABLEmissingrow + \handleTABLEerror + \fi + %\startHLcommand + \ifnum#1=\plusone + \global\advance\currentTABLEcolumn \plustwo + \let\next\normalTABLEsinglerule + \else + \ifnum#1<\maxTABLEcolumn + \global\advance\currentTABLEcolumn \plusone + \def\next{\normalTABLEmultirule{#1}}% + \else + \setTABLEerror\TABLEdivisionoverflow + \let\next\handleTABLEerror + \fi + \fi + \next + %\stopHLcommand + %\globalletempty\startHLcommand + %\globalletempty\stopHLcommand + \fi} + +\def\TableDV + {\TableDCV\normalTABLEsimplebar} + +\def\TableDC + {\TableDCV\normalTABLEquote} + +\def\TableDCV#1% + {\checkTABLEdivision + \checkTABLEautorow + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + \setTABLEerror\TABLEmissingrow + \handleTABLEerror + \else + \global\advance\currentTABLEcolumn \plusone + #1% + \fi} + +\def\TableDR + {\ifnum\currentTABLEcolumn<\maxTABLEcolumn % silent recovery + %\setTABLEerror\TABLEmissingcolumn % some day warning + %\handleTABLEerror + \finishTABLErow + \else + \global\currentTABLEcolumn\zerocount % nog check + \normalTABLElineending + \fi + \TABLEnoalign + {\nobreak + \global\TABLEdivisionfalse + \accountTABLElinewidth % temporary solution + \setTABLEaction\TABLErule}} + +\def\accountTABLElinewidth + {\scratchdimen\LineThicknessUnit} + +%D \startitemize[3*ruim] +%D \sym{\type{\BC}} +%D \sym{\type{\BR}} +%D \sym{\type{\BACKGROUND}} +%D \sym{\type{\CL}} +%D \sym{\type{\RL}} +%D \sym{\type{\BL}} +%D \sym{\type{\RASTER}} +%D \sym{\type{\COLOR}} +%D \stopitemize + +% definieer: \BC \BL +% herhaal: \BR +% definieer: \CL \RL (eerste \CL[green] = hele row! / \CL[1,green]) +% dus: \CL en \RL mix tussen \HL en \BL + +\def\defineTABLEbackgrounds + {\let\BC \TableBC + \let\BL \TableBL + \let\BR \TableBR + \let\BACKGROUND\TableBR + \let\CL \TableCL + \let\RL \TableRL + \let\COLOR \TableCOLOR + \let\RASTER \TableRASTER + \globallet\lastTABLEc\@@tibackgroundcolor + \globallet\lastTABLEr\@@tibackgroundscreen + \doifinsetelse\@@tibackground{c,color} % \v!color + {\global\chardef\TABLEcr\plusone} + {\global\chardef\TABLEcr\plustwo}} + +\def\TableBC + {\ifTABLEgrayline + \normalTABLEquote + \else + \TABLEnoalign\bgroup + \globallet\nextTABLEgrayline\executeTABLEgrayline + \globalletempty\TABLEgrayline % new + \let\BL\doTableBL + \let\BC\doTableBC + \expandafter\doTableBC + \fi} + +\def\doTableBC + {\addtoTABLEgrayline{\BC}% + \gobbleTableBCL} + +\def\TableBL + {\TABLEnoalign\bgroup + \globallet\nextTABLEgrayline\executeTABLEgrayline + \globalletempty\TABLEgrayline % new + \let\BL\doTableBL + \let\CL\doTableCL + \let\RL\doTableRL + \let\BC\doTableBC + \doTableBL} + +\def\doTableBL + {\complexorsimpleTable{BL}} + +\def\simpleTableBL + {\complexTableBL[,]} + +\def\complexTableBL[#1]% + {\analyzeTABLEcr[#1]% + \handleTABLEcr} + +\def\TableBR#1% + {\TABLEnoalign + {\globallet\nextTABLEgrayline\executeTABLEgrayline + \checkTABLEgrayline#1\BR + \global\TABLEgraylinetrue}} + +\def\analyzeTABLEcr[#1]% + {\doanalyzeTABLEcr[#1,,]} + +\def\doanalyzeTABLEcr[#1,#2,#3]% + {\doifnumberelse{#1x} % Is the x still needed here? + {\dodoanalyzeTABLEcr[#1,#2,#3]} + {\dodoanalyzeTABLEcr[1,#1,#2]}} + +\def\dodoanalyzeTABLEcr[#1,#2,#3]% + {\global\chardef\TABLEn#1\relax + \processaction + [#2] + [ c=>\global\chardef\TABLEcr1,% + color=>\global\chardef\TABLEcr1,% + r=>\global\chardef\TABLEcr2,% + raster=>\global\chardef\TABLEcr2]% + \ifcase\TABLEcr \or + \doifsomething{#3}{\xdef\lastTABLEc{#3}}% + \or + \doifsomething{#3}{\xdef\lastTABLEr{#3}}% + \fi} + +\def\handleTABLEcr + {\relax % else funny side effect + \ifcase\TABLEcr + % Can't happen! + \or + \addtoTABLEgrayline{\complexTableCOLOR[\the\TABLEn,\lastTABLEc]}% + \else + \addtoTABLEgrayline{\complexTableRASTER[\the\TABLEn,\lastTABLEr]}% + \fi + \gobbleTableBCL} + +\def\analyzeTABLEcrl#1[#2]% + {\doanalyzeTABLEcrl#1[#2,,]} + +\def\doanalyzeTABLEcrl#1[#2,#3,#4]% + {\doifnumberelse{#2x} % x ???????????????????? + {\dodoanalyzeTABLEcr[#2,#1,#3]} + {\dodoanalyzeTABLEcr[\ifTABLEgrayline1\else\maxTABLEcolumn\fi,#1,#2]}} + +\def\TableCL + {\TABLEnoalign\bgroup + \globallet\nextTABLEgrayline\executeTABLEgrayline + \globalletempty\TABLEgrayline % new + \let\BL\doTableBL + \let\CL\doTableCL + \let\RL\doTableRL + \let\BC\doTableBC + \doTableCL} + +\def\doTableCL + {\complexorsimpleTable{CL}} + +\def\simpleTableCL% nog eens \'e\'en lijn van maken + {\BL[\the\maxTABLEcolumn,c,\lastTABLEc]} + +\def\complexTableCL[#1]% + {\analyzeTABLEcrl{c}[#1]% + \handleTABLEcr} + +\def\TableRL + {\TABLEnoalign\bgroup + \globallet\nextTABLEgrayline\executeTABLEgrayline + \globalletempty\TABLEgrayline % new + \let\BL\doTableBL + \let\CL\doTableCL + \let\RL\doTableRL + \let\BC\doTableBC + \doTableRL} + +\def\doTableRL + {\complexorsimpleTable{RL}} + +\def\simpleTableRL + {\BL[\the\maxTABLEcolumn,r,\lastTABLEr]} + +\def\complexTableRL[#1]% + {\analyzeTABLEcrl{r}[#1]% + \handleTABLEcr} + +\def\checkTABLEgrayline#1#2% + {\!!doneatrue + \ifx#1\AR + \!!doneafalse + \else\ifx#1\SR\else\ifx#1\FR\else\ifx#1\MR\else\ifx#1\LR\else + \!!doneafalse + \fi\fi\fi\fi\fi + \if!!donea + \gdef\TABLEgraylinestatus + {[\string#1]}% + \gdef\TABLEendBCL + {#1}% + \else + \gdef\TABLEgraylineerror + {[\string#2\string#1->\string#2\string\SR]}% + \gdef\TABLEendBCL + {\SR}% + \fi} + +\def\endTABLErowGL#1#2#3% + {\ifcase#1\relax + % unknown + \or + \doPreTableGL\TABLErowfactor\TABLErowfactor + \or + \doPreTableGL\TABLErowfactor\TABLErowzero + \or + \ifnum\TABLEforce=\TABLEforcelastrow + \doPreTableGL\TABLErowzero\TABLErowfactor + \else\ifnum\TABLEforce=\TABLEforcefirstrow + \doPreTableGL\TABLErowfactor\TABLErowzero + \else + \doPreTableGL\TABLErowzero\TABLErowzero + \fi\fi + \or + \doPreTableGL\TABLErowzero\TABLErowfactor + \fi} + +\def\doPreTableGL#1#2% betere namen + {\xdef\OldLineThicknessFactor{\the\LineThicknessFactor}% + \xdef\OldLineThicknessUnit{\the\LineThicknessUnit}% + \global\LineThicknessFactor\plusone + \setbox0\hbox{\AugmentedTableStrut{#1}{#2}}% + \getboxheight\dimen0\of\box0\relax + \xdef\TABLEgraylineHeight{\the\dimen0}% + \global\LineThicknessUnit\TABLEgraylineHeight} + +\def\doPostTableGL + {\global\LineThicknessFactor\OldLineThicknessFactor + \global\LineThicknessUnit \OldLineThicknessUnit} + +% kan simpeler + +\def\docomplexTableCOLOR[#1]% + {\dodocomplexTableGL\localstartcolor \localstopcolor [#1,\lastTABLEc,,]} + +\gdef\docomplexTableRASTER[#1]% + {\dodocomplexTableGL\localstartraster\localstopraster[#1,\lastTABLEr,,]} + +\def\dodocomplexTableGL#1#2[#3,#4,#5,#6]% + {\doifelsenothing{#4}{#1[#5]}{#1[#4]}% + \doPreTableGL\TABLEendofrowheight\TABLEendofrowdepth + \ifnum#3=\plusone % else conflict with \omit in \= + \let\next\normalTABLEsinglerule + \else + \def\next{\normalTABLEmultirule{#3}}% + \fi + \next + \doPostTableGL + #2} + +\def\TableBACKGROUND + {\TableBR} + +\def\simpleTableRASTER #1{\docomplexTableRASTER[1]#1} +\def\complexTableRASTER[#1]{\docomplexTableRASTER[#1]} +\def\simpleTableCOLOR {\docomplexTableCOLOR [1]} +\def\complexTableCOLOR [#1]{\docomplexTableCOLOR [#1]} + +\def\TableRASTER{\complexorsimpleTable{RASTER}} +\def\TableCOLOR {\complexorsimpleTable{COLOR}} + +\def\addtoTABLEgrayline#1% + {\TABLEgraytoks\expandafter{\TABLEgrayline}% + \xdef\TABLEgrayline{\the\TABLEgraytoks\noexpand#1}} + +\def\setTableBCL#1#2% + {\ifx#1#2% + \gdef\TABLEgraylinestatus{[\string#1]}% + \gdef\TABLEendBCL{#1}% + \addtoTABLEgrayline{#1}% + \else + \gdef\TABLEgraylineerror{[\string#1->\string#2]}% + \gdef\TABLEendBCL{#2}% + \addtoTABLEgrayline{#2}% + \fi} + +\def\gobbleTableBCL#1% + {\ifx#1\BC \let\next\doTableBC \else + \ifx#1\BL \let\next\doTableBL \else + \ifx#1\SR \setTableBCL\SR\SR \let\next\egroup \else + \ifx#1\FR \setTableBCL\FR\FR \let\next\egroup \else + \ifx#1\MR \setTableBCL\MR\MR \let\next\egroup \else + \ifx#1\LR \setTableBCL\LR\LR \let\next\egroup \else + \setTableBCL #1\SR \let\next\egroup + \fi\fi\fi\fi\fi\fi + \next} + +\def\executeTABLEgrayline + {\TABLEnoalign + {\def\BC + {\advance\currentTABLEcolumn \plusone}% + \def\dodocomplexTableGL##1##2[##3,##4,##5,##6]% + {\BC\advance\currentTABLEcolumn ##3 }% + \let\endTABLErow\endTABLEgrayrow + \currentTABLEcolumn\zerocount + \TABLEgrayline\TABLEendBCL % determine n of columns and height + \advance\currentTABLEcolumn \minusone + \ifnum\currentTABLEcolumn>\maxTABLEcolumn + % error message too long line + \globalletempty\TABLEgrayline + \else + % \message{n of color columns: \the\currentTABLEcolumn}\wait + \global\TABLEgraylinetrue % vanaf hier nog checken + \fi + \global\currentTABLEcolumn\zerocount}% + \unskip\TABLEgrayline\TABLEendBCL + \TABLEnoalign + {\nobreak + \vskip-\TABLEgraylineHeight + \nobreak + \global\setTABLEactiontrue + \global\currentTABLEcolumn\zerocount + \globalletempty\nextTABLEgrayline + \global\TABLEgraydonetrue + \global\TABLEgraylinefalse}} + +\def\endTABLEgrayrow#1#2#3% + {\ifcase#1\relax + \global\chardef\TABLEendofrowheight\TABLErowfactor + \global\chardef\TABLEendofrowdepth \TABLErowfactor + \or + \global\chardef\TABLEendofrowheight\TABLErowfactor + \global\chardef\TABLEendofrowdepth \TABLErowfactor + \or + \global\chardef\TABLEendofrowheight\TABLErowfactor + \global\chardef\TABLEendofrowdepth \TABLErowzero + \or + \ifnum\TABLEforce=\TABLEforcelastrow + \global\chardef\TABLEendofrowheight\TABLErowzero + \global\chardef\TABLEendofrowdepth \TABLErowfactor + \else\ifnum\TABLEforce=\TABLEforcefirstrow + \global\chardef\TABLEendofrowheight\TABLErowfactor + \global\chardef\TABLEendofrowdepth \TABLErowzero + \else + \global\chardef\TABLEendofrowheight\TABLErowzero + \global\chardef\TABLEendofrowdepth \TABLErowzero + \fi\fi + \or + \global\chardef\TABLEendofrowheight\TABLErowzero + \global\chardef\TABLEendofrowdepth \TABLErowfactor + \fi} + +\def\defineTABLEshorthands% + {\def\SPAN##1{\use{##1}}% + \def\TWO {\use2}% + \def\THREE {\use3}% + \def\FOUR {\use4}% + \def\FIVE {\use5}% + \def\SIX {\use6}% + \def\REF {\ReFormat}} + +\def\defineTABLEunits + {\processaction + [\@@tidistance] + [ \v!none=>\OpenUp00\def\LOW{\Lower6 }, + \v!small=>\OpenUp00\def\LOW{\Lower6 }, % == baseline + \v!medium=>\OpenUp11\def\LOW{\Lower7 }, + \v!big=>\OpenUp22\def\LOW{\Lower8 }]% + \doifelse\@@tidistance\v!none + {\chardef\TABLErowfactor\zerocount} + {\chardef\TABLErowfactor\plustwo }} + +\def\dohandlebar % here ? + {\ifmmode + \@EA\domathmodebar + \else\ifintable + \@EAEAEA\domathmodebar + \else + \@EAEAEA\dotextmodebar + \fi\fi} + +% De macro's t.b.v. instellingen. + +\def\setuptables + {\dosingleargument\dosetuptables} + +\def\dosetuptables[#1]% + {\getparameters[\??ti][#1]% + \processaction + [\@@tialign] + [ \v!right=>\def\TABLEparalignment{\raggedright}, + \v!left=>\def\TABLEparalignment{\raggedleft}, + \v!middle=>\def\TABLEparalignment{\raggedcenter}, + \s!default=>\def\TABLEparalignment{\notragged}, + \s!unknown=>\def\TABLEparalignment{\notragged}]% + \assignalfadimension\@@tiVL\@@tiVLwidth 246% + \assignalfadimension\@@tiHL\@@tiHLheight246} + +\def\localTABLEsetup + {\@@ticommands\relax + \expanded{\switchtobodyfont[\@@tibodyfont]}% + \StrutHeightFactor 8 + \StrutDepthFactor 4 + \LineThicknessFactor4 + \NormalTLTU {.1pt}% + \NormalTSU {\normalbaselineskip\divide\StrutUnit 12 }% + \NormalTableUnits} + +%D And then I wrote the tabulate environment. That +%D alternative supports setting the rule thickness and color, +%D so here is the table alternative. + +\let\startglobalTABLEcolor\empty +\let\stopglobalTABLEcolor \empty + +\def\localTABLEsetup + {\@@ticommands\relax + % bodyfont + \expanded{\switchtobodyfont[\@@tibodyfont]}% + % linecolor + \doifsomething\@@tirulecolor + {\def\startglobalTABLEcolor{\localstartcolor[\@@tirulecolor]}% + \def\stopglobalTABLEcolor {\localstopcolor}}% + % linethickness + \LineThicknessFactor4 + \scratchdimen\@@tirulethickness + \divide\scratchdimen \LineThicknessFactor + \expanded{\NormalTLTU{\the\scratchdimen}}% + % spacing, was depth=4 height=8 (counters, sigh, now macros) + \doifelse\@@tiheight\v!strut + {\let\StrutHeightFactor\@@itheight} + {\let\StrutHeightFactor\@@tiheight}% + \doifelse\@@tidepth\v!strut + {\let\StrutDepthFactor\@@itdepth} + {\let\StrutDepthFactor\@@tidepth}% + \scratchdimen\StrutHeightFactor\points \multiply\scratchdimen 10% + \edef\StrutHeightFactor{\withoutpt\the\scratchdimen}% + \scratchdimen\StrutDepthFactor \points \multiply\scratchdimen 10% + \edef\StrutDepthFactor{\withoutpt\the\scratchdimen}% + % units + \NormalTSU{\normalbaselineskip\divide\StrutUnit 12 }% + \NormalTableUnits} + +\def\OpenUp#1#2% + {\scratchdimen\StrutHeightFactor \points \advance\scratchdimen #1\points + \edef\StrutHeightFactor{\withoutpt\the\scratchdimen}% + \scratchdimen\StrutDepthFactor \points \advance\scratchdimen #2\points + \edef\StrutDepthFactor{\withoutpt\the\scratchdimen}} + +%D As one can see, we didn't only add color, but also more +%D control over spacing. +%D +%D \startbuffer[a] +%D \starttable[|c|] +%D \HL +%D \VL \strut test \VL \FR +%D \VL \strut test \VL \MR +%D \VL \strut test \VL \MR +%D \VL \strut test \VL \LR +%D \HL +%D \stoptable +%D \stopbuffer +%D +%D \startbuffer[b] +%D \starttabulate[|c|] +%D \HL +%D \NC test \NC \NR +%D \NC test \NC \NR +%D \NC test \NC \NR +%D \NC test \NC \NR +%D \HL +%D \stoptabulate +%D \stopbuffer +%D +%D In the next example, the first table is defined as: +%D +%D \typebuffer[a] +%D +%D and the second one as: +%D +%D \typebuffer[b] +%D +%D The first table is typeset using the default height and +%D depth factors .8 and .4. The second table has both factors +%D set to \type {strut}, and the third table shows what +%D happens when we set the values to zero. The rightmost table +%D is typeset using the tabulate environment. +%D +%D \startcombination[4*1] +%D {$\vcenter{\getbuffer[a]}$} +%D {\hbox{h=.8 d=.4}} +%D {\setuptables[height=strut,depth=strut]$\vcenter{\getbuffer[a]}$} +%D {\hbox{h=d=\type{strut}}} +%D {\setuptables[height=0,depth=0]$\vcenter{\getbuffer[a]}$} +%D {\hbox{h=d=0}} +%D {$\vcenter{\getbuffer[b]}$} +%D {\hbox{tabulate}} +%D \stopcombination + +\setuptables + [HL=\v!medium, + VL=\v!medium, + NL=\v!small, + \c!frame=, + \c!align=\v!right, + \c!depth=.40, % \v!strut + \c!height=.80, % \v!strut + \c!rulethickness=\linewidth, + \c!rulecolor=, + \c!distance=\v!medium, + \c!bodyfont=\the\bodyfontsize, + \c!commands=, + \c!background=\v!screen, + \c!backgroundscreen=\@@rsscreen, + \c!backgroundcolor=, + \c!split=\v!auto] + +\def\ifintabel{\ifintable} % upward compatible + +\protect \endinput diff --git a/tex/context/base/tabl-tbl.tex b/tex/context/base/tabl-tbl.tex new file mode 100644 index 000000000..bc57a3abd --- /dev/null +++ b/tex/context/base/tabl-tbl.tex @@ -0,0 +1,1435 @@ +%D \module +%D [ file=core-tbl, +%D version=1998.11.03, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Text Flow Tabulation, +%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 Table Macros / Tabulation} + +% \processbetween gebruiken in head/tail macros + +\unprotect + +% WATCH OUT: don't change this model else trialtypesetting +% compatibility problems + +% watch out, cells expand pretty late on a per row basis + +% |p2|p3| 2:3 +% spanning + +% Be careful with changing the hsize calculation in p mode; +% the following code works quite well: +% +% \setupfield [line][location=low,height=1.2\lineheight,width=\hsize] +% \definefield [test] [line] [line] [] +% +% \starttabulate[|l|p|] +% \NC test \NC \field [test] \NC \NR +% \stoptabulate + +% In-text tabbing environment +% +% \starttabulate[| separated template] % eg [|l|p|] or [|l|p|p|] +% \NC ... \NC ... \NC\NR +% \stoptabulate +% +% with: two pass auto width calculation when no p-width +% specified, even with multiple p's, see examples. + +% TaBlE compatible specifications: +% +% l align column/paragraph left +% r align column/paragraph right +% c align column/paragraph center +% p p(dimen) of automatisch als alleen p +% w column width +% f font#1 +% B bold +% I italic +% S slanted +% T type +% R roman +% m math +% M display math +% h hook (inner level or par lines) +% b before (may be command#1) +% a after +% i i skip left of column +% j i skip right of column +% k i skip around column + +% s setups + +% g g{char} align at char +% . align at . +% , align at , + +% Still to be done + +% N math numbers (best hook into existing digits mechanism) +% n numbers (best hook into existing digits mechanism) +% Q math numbers (best hook into existing digits mechanism) +% q numbers (best hook into existing digits mechanism) +% ~ \hskip.5em +% | check + +% nesting + +% 10 evt auto stack; dan wel andere signal dan void nodig + +% present but not yet 100% ok +% +% \FL top hrule +% \ML mid hrule (with auto split) +% \LL bottom hrule +% \HL + +% \VL as soon as needed +% color as soon as needed + +% \EQ \RQ \HQ equal (raw, hook) +% \NC \RC \HC normal (raw, hook) +% +% \NR + +% \HR : rule with lineheight + +% \autotabulaterule : with lineheight, not first/last +% \autotabulateline : spaced, not first/last +% \tabulaterule : with lineheight +% \tabulateline : spaced + +% tricky: align scans ahead, over # and expands ones before +% while doing + +% new: +% +% \starttabulate[|cg{.}|cg{,}|cg{,}|] +% \NC period \NC comma \NC comma \NC\NR +% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR +% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR +% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR +% \NG 10 \NG 10 \NG 0,00 \NC\NR +% \stoptabulate +% +% \starttabulate[|c.|c,|c,|] +% \NC period \NC comma \NC comma \NC\NR +% \NG 100.000,00 \NG 100.000,00 \NG 100,00 \NC\NR +% \NG 10.000,00 \NG 10.000,00 \NG 1000,00 \NC\NR +% \NG 100,00 \NG 100,00 \NG 10,00 \NC\NR +% \NG 10 \NG 10 \NG 0,00 \NC\NR +% \stoptabulate + +% nice demo (for BG) +% +% \starttabulate[|r|b{$\star$}|ra{\percent}|b{=}|r|] +% \NC 500 \NC \NC 60 \NC \NC 300 \NC \NR +% \NC 500 \NC \NC 55 \NC \NC 275 \NC \NR +% \NC 500 \NC \NC 50 \NC \NC 250 \NC \NR +% \NC 500 \NC \NC 45 \NC \NC 225 \NC \NR +% \NC 500 \NC \NC 40 \NC \NC 200 \NC \NR +% \NC 500 \NC \NC 35 \NC \NC 175 \NC \NR +% \NC 500 \NC \NC 30 \NC \NC 150 \NC \NR +% \NC 500 \NC \NC 25 \NC \NC 125 \NC \NR +% \NC 500 \NC \NC 20 \NC \NC 100 \NC \NR +% \stoptabulate + +\newtoks \tabulatepreamble +\newtoks \tabulatebefore +\newtoks \tabulateafter +\newtoks \tabulatebmath +\newtoks \tabulateemath +\newtoks \tabulatefont +\newtoks \tabulatesettings +\newtoks \tabulatedummy + +\newcount \nofautotabulate +\newcount \tabulatecolumns +\newcount \tabulatecolumn + +\newcount \tabulateminplines +\newcount \tabulatemaxplines + +\newif \ifautotabulate +\newif \ifsplittabulate \splittabulatetrue + +\newif \ifhandletabulatepbreak \handletabulatepbreaktrue +\newif \iftabulatenopbreak \tabulatenopbreakfalse + +\newif \iftabulateequal +\newif \iftracetabulate +\newif \ifframedtabulate + +\newdimen \tabulatepwidth +\newdimen \tabulatewidth +\newdimen \tabulateunit +\newdimen \tabulatemaxpheight + +\newbox \tabulatebox + +% [|lg{.}|] => \NG 12.34 \NC + +\gdef\handletabulatecharalign#1 % space delimited ! + {\edef\alignmentclass{\the\tabulatecolumn}% + \edef\alignmentcharacter{\getvalue{\@@tabalign@@\the\tabulatecolumn}}% + \ifcase\tabulatepass\or + \setfirstpasscharacteralign\checkalignment{#1}% + \fi % force hsize + \setsecondpasscharacteralign\checkalignment{#1}} + +\def\noftabcolumns{16} + +\def\@@tabbox@@ {@@tabbox@} +\def\@@tabhook@@ {@@tabhook@} +\def\@@tabalign@@ {@@tabalign@} +\def\@@tabsetups@@{@@tabsetups@} + +% \dorecurse\noftabcolumns % quick and dirty stack +% {\@EA\newbox\csname\@@tabbox@@\recurselevel\endcsname} + +\def\tablebox#1% + {\csname\@@tabbox@@\number#1\endcsname} + +% \def\checktablebox#1% +% {\ifundefinedelse{\@@tabbox@@\number#1}% +% \expandafter\newbox\csname\@@tabbox@@\number#1\endcsname +% \fi} + +\def\initializetablebox#1% also used elsewhere + {\ifcsname\@@tabbox@@\number#1\endcsname + \global\setbox\csname\@@tabbox@@\number#1\endcsname\emptybox + \else + \expandafter\newbox\csname\@@tabbox@@\number#1\endcsname + \fi} + +% \def\initializetableboxes#1% hm, not that efficient, best make a simple dedicated tail recurser +% {\dorecurse#1{\initializetablebox\recurselevel}} + +\def\initializetableboxes#1% + {\scratchcounter#1\relax + \doinitializetableboxes} + +\def\doinitializetableboxes + {\ifnum\scratchcounter>\zerocount + \initializetablebox\scratchcounter + \advance\scratchcounter\minusone + \expandafter\doinitializetableboxes + \fi} + +\initializetableboxes\noftabcolumns + +\def\dotabulatenobreak + {\noalign + {\nobreak + \iftracetabulate + \red\hrule\!!height.5\linewidth\!!depth.5\linewidth + \par + \kern-\linewidth + \nobreak + \fi}} + +\let\notabulatehook\empty + +\def\checktabulatehook + {\ifnum\tabulatetype<\plustwo + \global\let\tabulatehook\notabulatehook + \else + \global\let\tabulatehook\dotabulatehook + \fi} + +\def\checktabulatesetups + {\getvalue{\@@tabsetups@@\the\tabulatecolumn}} + +\let\pretabrule \donothing +\let\posttabrule\donothing + +\def\dodosettabulatepreamble#1#2% + {\ifzeropt\tabulatewidth + \ifcase\tabulatemodus\relax + \let\preamblebox\empty + \else + \def\preamblebox{\autotabulatetrue}% + \fi + \else + \ifcase\tabulatemodus\relax + \edef\preamblebox{\hbox to \the\tabulatewidth}% + \else + \edef\preamblebox{\hsize\the\tabulatewidth}% + \fi + \fi + % + % less bytes + % + %\edef\preamblebox% + % {\ifcase\tabulatewidth + % \ifcase\tabulatemodus\relax\else\noexpand\autotabulatetrue\fi + % \els + % \ifcase\tabulatemodus\relax\hbox to\else\hsize\fi\the\tabulatewidth + % \fi}% + % + % 0 = NC column next EQ equal column + % 1 = RC column raw RQ equal column raw + % 2 = HC column hook HQ equal column hook + % some entries can be left out if we test for them being set + \@EA\appendtoks \@EA&\@EA\hskip\pretabskip\pretabrule##&\to\!!toksa + \appendtoks \ignorespaces\to\!!toksa + \@EA\appendtoks\@EA\global\@EA\tabulatecolumn\the\tabulatecolumns\relax\to\!!toksa + \appendtoks \checktabulatesetups\to\!!toksa + \appendtoks \checktabulatehook\to\!!toksa + \@EA\appendtoks \preamblebox\to\!!toksa + \appendtoks \bgroup\bbskip\bgroup#1\to\!!toksa + \appendtoks\ifnum\tabulatetype=\plusone \else \to\!!toksa + \@EA\appendtoks \the\tabulatebmath\to\!!toksa + \@EA\appendtoks \the\tabulatefont\to\!!toksa + \@EA\appendtoks \the\tabulatesettings\to\!!toksa + \@EA\appendtoks \the\tabulatebefore\to\!!toksa + \appendtoks\fi \to\!!toksa + \appendtoks \bgroup\ignorespaces\to\!!toksa + % + \appendtoks \tabulatehook##\to\!!toksa + % + %%\doifdefinedelse{\@@tabalign@@\tabulatecolumns} + %\doifdefinedelse{\@@tabalign@@\the\tabulatecolumns} + % {\appendtoks\handletabulatecharalign## \to\!!toksa} + % {\appendtoks\tabulatehook ##\to \!!toksa}% + % waarom kan ik hier geen \xx{##} geven, om een of + % andere reden passeert dan tex de hele regel (incl \NC's) + % als argument; elke delimiter <> space gaat trouwens fout + \appendtoks \unskip\unskip\ifmmode\else\endgraf\fi\egroup\to\!!toksa + \appendtoks\ifnum\tabulatetype=1 \else \to\!!toksa + \@EA\appendtoks \the\tabulateafter\to\!!toksa + \@EA\appendtoks \the\tabulateemath\to\!!toksa + \appendtoks\fi \to\!!toksa + \appendtoks #2\egroup\egroup\to\!!toksa + \@EA\appendtoks \@EA&\@EA\posttabrule\@EA\hskip\postabskip##\to\!!toksa + \appendtoks\NC\to\tabulatedummy + \let\bbskip\empty + \def\pretabskip{.5\tabulateunit}% + \let\postabskip\pretabskip + \let\gettabulateexit\dogettabulateexit + \tabulatewidth\zeropoint} + +% todo: we can speed up this module a bit +% +% \expanded{\!!toksa{\the\!!toksa +% &\hskip\pretabskip\noexpand\pretabrule####& +% \ignorespaces +% \global\tabulatecolumn\the\tabulatecolumns +% \noexpand\checktabulatesetups +% \noexpand\checktabulatehook +% \preamblebox +% \bgroup\noexpand\bbskip\bgroup\normalunexpanded{#1}% +% \noexpand\ifnum\tabulatetype=\plusone \noexpand\else +% \the\tabulatebmath +% \the\tabulatefont +% \the\tabulatesettings +% \the\tabulatebefore +% \noexpand\fi +% \bgroup\ignorespaces +% \noexpand\tabulatehook####% +% \unskip\unskip\noexpand\ifmmode\noexpand\else\endgraf\noexpand\fi\egroup +% \noexpand\ifnum\noexpand\tabulatetype=1 \noexpand\else +% \the\tabulateafter +% \the\tabulateemath +% \noexpand\fi +% \normalunexpanded{#2}\egroup\egroup +% &\noexpand\posttabrule\hskip\noexpand\postabskip####}}% + +\def\dosettabulatepreamble + {\ifx\next\relax + \let\nextnext\relax % == \expandafter\gobbleoneargument + \else + \let\nextnext\settabulatepreamble + \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 + \else\ifx f\next \let\nextnext\gettabulatefont + \else\ifx B\next \tabulatefont{\bf}% + \else\ifx I\next \tabulatefont{\it}% + \else\ifx S\next \tabulatefont{\sl}% + \else\ifx T\next \tabulatefont{\tt}% + \else\ifx R\next \tabulatefont{\rm}% + \else\ifx m\next \tabulatebmath{$}\tabulateemath{$}% + \else\ifx M\next \tabulatebmath{$\displaystyle}\tabulateemath{$}% + \else\ifx h\next \let\nextnext\gettabulatehook + \else\ifx b\next \let\nextnext\gettabulatebefore + \else\ifx a\next \let\nextnext\gettabulateafter + \else\ifx i\next \let\nextnext\gettabulatepreskip + \else\ifx j\next \let\nextnext\gettabulateposskip + \else\ifx k\next \let\nextnext\gettabulatepreposskip + \else\ifx X\next \let\nextnext\gettabulateexit % internal + \else\ifx e\next \appendtoks\global\tabulateequaltrue\to\tabulatesettings + \else\ifx ~\next \appendtoks\fixedspaces\to\tabulatesettings + \else\ifx g\next \let\nextnext\gettabulatealign + \else\ifx .\next \def\nextnext{\gettabulatealign.}% + \else\ifx ,\next \def\nextnext{\gettabulatealign,}% + \else \message{unknown preamble key [\meaning\next]}% + \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi \fi\fi + \fi + \nextnext} + +\def\dogettabulateexit + {\let\postabskip\!!zeropoint + \settabulatepreamble} + +\let\gettabulateexit\dogettabulateexit + +\def\gettabulatepreskip#1% + {\doifnumberelse{#1} + {\scratchdimen#1\tabulateunit\let\next\empty} + {\scratchdimen.5\tabulateunit\def\next{#1}}% + \edef\pretabskip{\the\scratchdimen}% + \@EA\settabulatepreamble\next} + +\def\gettabulateposskip#1% + {\doifnumberelse{#1} + {\scratchdimen#1\tabulateunit\let\next\empty} + {\scratchdimen.5\tabulateunit\def\next{#1}}% + \edef\postabskip{\the\scratchdimen}% + \let\gettabulateexit\settabulatepreamble + \@EA\settabulatepreamble\next} + +\def\gettabulatepreposskip#1% + {\doifnumberelse{#1} + {\scratchdimen#1\tabulateunit\let\next\empty} + {\scratchdimen.5\tabulateunit\def\next{#1}}% + \edef\pretabskip{\the\scratchdimen}% + \let\postabskip\pretabskip + \let\gettabulateexit\settabulatepreamble + \@EA\settabulatepreamble\next} + +\def\gettabulatesetups#1% + {\setvalue{\@@tabsetups@@\the\tabulatecolumns}{\setups[#1]}% + \settabulatepreamble} + +\def\gettabulatehook#1% + {\setvalue{\@@tabhook@@\the\tabulatecolumns}{#1}% + \settabulatepreamble} + +\def\gettabulatealign#1% + {\setvalue{\@@tabalign@@\the\tabulatecolumns}{#1}% + \settabulatepreamble} + +\def\gettabulatebefore#1% + {\tabulatebefore{#1}% + \settabulatepreamble} + +\def\gettabulateafter#1% + {\tabulateafter{#1}% + \settabulatepreamble} + +\def\gettabulatefont#1% + {\tabulatefont{#1}% + \settabulatepreamble} + +\def\gettabulatewidth + {\let\tabulatemodus\zerocount + \let\tabulatedimen\zerocount + \doifnextcharelse(\dogettabulatewidth\settabulatepreamble} + +\def\gettabulateparagraph + {\doifnextcharelse{(} + {\let\tabulatemodus\plusone + \let\tabulatedimen\plusone + \dogettabulatewidth} + {\let\tabulatemodus\plustwo + \let\tabulatedimen\zerocount + \settabulatepreamble}} + +% \def\dogettabulatewidth(#1)% +% {\tabulatewidth#1\relax +% \ifnum\tabulatedimen=\plusone +% \global\advance\tabulatepwidth\tabulatewidth +% \fi +% \settabulatepreamble} + +% \def\dogettabulatewidth(#1)% +% {\doifelse{#1}\v!passend +% {\let\tabulatemodus\plusthree} +% {\tabulatewidth#1\relax}% +% \ifnum\tabulatedimen=\plusone +% \global\advance\tabulatepwidth\tabulatewidth +% \fi +% \settabulatepreamble} + +% \startbuffer +% \toplinebox{\framed[width=3cm,height=2cm]{tufte}} +% \stopbuffer +% \starttabulate[|p(fixed)|p|] +% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR} +% \stoptabulate +% \starttabulate[|p(fit)|p|] +% \dorecurse{100}{\NC \getbuffer \NC test \par test \par \NC \NR} +% \stoptabulate + +\def\dogettabulatewidth(#1)% + {\processallactionsinset + [#1]% + [ \v!fit=>\let\tabulatemodus\plusthree, + \v!fixed=>\let\tabulatemodus\plusthree + \tabulatenopbreaktrue, + \s!unknown=>\tabulatewidth#1\relax]% + \ifnum\tabulatedimen=\plusone + \global\advance\tabulatepwidth\tabulatewidth + \fi + \settabulatepreamble} + +\def\settabulatepreamble + {\afterassignment\dosettabulatepreamble\let\next=} + +\def\tabulateraggedright {\ifnum\tabulatetype=\plusone \else\raggedright \fi} +\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} % never change this to a fill + +\bgroup \catcode`\|=\@@other + +\gdef\nexttabulate#1|% + {\let\tabulatealign\@@tabulatealign + \let\tabulatemodus\zerocount + \let\tabulatedimen\zerocount + \tabulatebefore \emptytoks + \tabulateafter \emptytoks + \tabulatebmath \emptytoks + \tabulateemath \emptytoks + \tabulatefont \emptytoks + \tabulatesettings\emptytoks + \global\advance\tabulatecolumns\plusone + \letvalue{\@@tabsetups@@\the\tabulatecolumns}\donothing + \settabulatepreamble#1\relax\relax % permits i without n + \ifcase\tabulatemodus\relax + \ifcase\tabulatealign\relax + \dodosettabulatepreamble\empty \tabulatehss \or + \dodosettabulatepreamble\empty \tabulatehss \or + \dodosettabulatepreamble\tabulatehss\empty \or + \dodosettabulatepreamble\tabulatehss\tabulatehss \fi + \or % fixed width + \ifcase\tabulatealign\relax + \dodosettabulatepreamble \bskip \eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedleft }\eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi + \or % auto width + \global\advance\nofautotabulate\plusone + \ifcase\tabulatealign\relax + \dodosettabulatepreamble \bskip \eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedright }\eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedleft }\eskip \or + \dodosettabulatepreamble{\bskip\tabulateraggedcenter}\eskip \fi + \or % simple + \dodosettabulatepreamble \xbskip \xeskip + \fi + \futurelet\next\donexttabulate} + +\egroup + +\def\donexttabulate + {\ifx\next\relax\else + \expandafter\nexttabulate + \fi} + +\def\splitofftabulatebox + {\dontcomplain + \global\setbox\tabulatebox % % % global ? % % % + \vsplit\tablebox\tabulatecolumn to \lineheight + \setbox\tabulatebox\normalvbox + {\unvbox\tabulatebox}% + \setbox\tabulatebox\hbox to \wd\tabulatebox + {\hss\dotabulatehook{\box\tabulatebox}\hss}% + \ht\tabulatebox\strutht + \dp\tabulatebox\strutdp + \box\tabulatebox} + +\def\dotabulatehook {\getvalue{\@@tabhook@@ \the\tabulatecolumn}} +\def\dotabulatealign {\getvalue{\@@tabalign@@ \the\tabulatecolumn}} + +\def\resettabulatepheight + {\global\tabulateminplines\plusone + \getnoflines\tabulatemaxpheight + \global\tabulatemaxplines\noflines + \global\tabulatemaxpheight\zeropoint} + +\def\settabulatepheight + {\scratchdimen\ht\tablebox\tabulatecolumn\relax + \ifdim\scratchdimen>\tabulatemaxpheight + \global\tabulatemaxpheight\scratchdimen + \fi} + +\def\handletabulatepbreak + {\TABLEnoalign + {\ifhandletabulatepbreak + \iftabulatenopbreak + \dotabulatenobreak + \else\ifnum\tabulatemaxplines>\plusone + \ifnum\tabulateminplines=\plusone + \dotabulatenobreak + \fi + \global\advance\tabulateminplines\plusone + \ifnum\tabulateminplines=\tabulatemaxplines\relax + \dotabulatenobreak + \fi + \fi \fi + \fi}} + +%D \startbuffer +%D \starttabulate[|c|p|p|] +%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR +%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR +%D \NC 2 \NC \thinrules[n=3] \NC \thinrules[n=3] \NC\NR +%D \NC 3 \NC oh yes \NC simply no \NC\NR +%D \NC 4 \NC very true \NC as false as can be \NC\NR +%D \NC 5 \NC \thinrules[n=5] \NC \thinrules[n=5] \NC\NR +%D \NC 6 \NC \thinrules[n=3] \NC \thinrules[n=4] \NC\NR +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer {\tracetabulatetrue\getbuffer} +%D +%D \startbuffer +%D \starttabulate[|c|p|p|] +%D \NC \bf Alpha \NC \bf Beta \NC \bf Gamma \NC\NR +%D \NC 1 \NC right indeed \NC definitely wrong \NC\NR +%D \NC 2 \NC oh yes \NC simply no \NC\NR +%D \NC 3 \NC very true \NC as false as can be \NC\NR +%D \NC 4 \NC the whole truth \NC but the truth \NC\NR +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer {\tracetabulatetrue\getbuffer} + +% \definetabulate +% \redefinetabulate +% \starttabulate[preamble] +% \starttabulate -> \starttabulate[|l|p|] + +\bgroup \catcode`\|=\@@other + +\gdef\definetabulate + {\dotripleempty\dodefinetabulate} + +\gdef\dodefinetabulate[#1][#2][#3]% + {\ifthirdargument + \doifundefined{\??tt#1::\c!unit} + {\copyparameters + [\??tt#1::][\??tt\v!tabulate::]% + [\c!frame,\c!distance,\c!unit,\c!before,\c!bodyfont,\c!after, + \c!inner,\c!indenting,\c!margin,\c!align,\c!header,\c!title, + \c!rulecolor,\c!rulethickness,\c!split,EQ]}% + \copyparameters + [\??tt#1::#2][\??tt#1::]% + [\c!unit,\c!distance,\c!before,\c!bodyfont,\c!after, + \c!inner,\c!indenting,\c!frame,\c!split,\c!header,\c!title, + \c!margin,\c!align,\c!rulecolor,\c!rulethickness,EQ]% + \setvalue{\e!start#1::#2}{\dofinalstarttabulate[#1][#2][#3]}% + \setvalue{\e!start#1}{\bgroup\dosubstarttabulate[#1]}% + \letvalue{\??tt#1-\v!header}\empty + \letvalue{\??tt#1-\v!footer }\empty + \else\ifsecondargument + \definetabulate[#1][][#2]% + \else + \definetabulate[#1][][|l|p|]% + \fi\fi} + +\egroup + +\let\tabulateheadcontent\empty +\let\tabulatetailcontent\empty + +\newconditional\tabulatesomeamble + +\def\checkfulltabulatecontent % - needed, else confusion with \c!header + {\ifundefined{\??tt\currenttabulate-\v!header}% + \let\tabulateheadcontent\empty + \else + \def\tabulateheadcontent + {\TABLEnoalign{\global\settrue\tabulatesomeamble}% + \csname\??tt\currenttabulate-\v!header\endcsname + \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% + \fi + \ifundefined{\??tt\currenttabulate-\v!footer}% + \let\tabulatetailcontent\empty + \else + \def\tabulatetailcontent + {\TABLEnoalign{\global\settrue\tabulatesomeamble}% + \csname\??tt\currenttabulate-\v!footer\endcsname + \TABLEnoalign{\global\setfalse\tabulatesomeamble}}% + \fi} + +% \def\fulltabulatecontent +% {\tabulateheadcontent +% \tabulatecontent +% \tabulatetailcontent} + +\def\fulltabulatecontent + {\tabulateheadcontent + \tabulatecontent + \tabulatetailcontent + \removefunnytabulateline} + +\def\removefunnytabulateline + {\ifhmode + \strut\crcr + \TABLEnoalign{\kern-\lineheight}% + \fi} + +\setvalue{\e!start\v!tabulatehead}% + {\dosingleempty\dostartstarttabulatehead} + +\def\dostartstarttabulatehead[#1]% + {\processcontent{\e!stop\v!tabulatehead}\next + {\letvalue{\??tt\iffirstargument#1\else\v!tabulate\fi::-\v!header}\next}} + +\setvalue{\e!start\v!tabulatetail}% + {\dosingleempty\dostartstarttabulatetail} + +\def\dostartstarttabulatetail[#1]% + {\processcontent{\e!stop\v!tabulatetail}\next + {\letvalue{\??tt\iffirstargument#1\else\v!tabulate\fi::-\v!footer}\next}} + +\def\dosubstarttabulate + {\dodoubleempty\dodosubstarttabulate} + +\def\dodosubstarttabulate[#1][#2]% + {\getvalue{\e!start#1::\ifundefined{\e!start#1::#2}\else#2\fi}} + +\setvalue{\e!start\v!tabulate}% + {\bgroup\dodoubleempty\donormalstarttabulate} + +\bgroup + +\gdef\donormalstarttabulate[#1][#2]% + {\ifsecondargument + \getparameters[\??tt\v!tabulate::][#2]% + \fi + \iffirstargument + \def\next{\dofinalstarttabulate[\v!tabulate][][#1]}% + \else + \def\next{\dofinalstarttabulate[\v!tabulate][][|l|p|]}% + \fi + \next} + +\egroup + +% The much neede hook: + +\newtoks\everytabulate + +% An example of its usage: + +\appendtoks \optimizeverbatimfalse \to \everytabulate +\appendtoks \let\recodeverbatimmode\plustwo \to \everytabulate + +% A status variable: + +\chardef\tabulatepass=0 + +\def\tabulateparameter#1{\csname\??tt\currenttabulate#1\endcsname} + +\bgroup + \catcode`\|=\@@other \gdef\@@otherbar{|} + \catcode`\|=\@@active \gdef\@@useotherbar{\let|\@@otherbar} +\egroup + +\def\dofinalstarttabulate[#1][#2][#3]% identifier sub preamble + {\edef\currenttabulate{#1::#2}% + \ifinsidefloat \else + \whitespace + \tabulateparameter\c!before + \fi + \bgroup + \resetcharacteralign + % todo: spacing around tabulate when bodyfont is set + % expansion en test needed ? + \splittabulatetrue + \processaction + [\tabulateparameter\c!split] + [% \v!yes=>\splittabulatetrue, + % \v!repeat=>\splittabulatetrue, % todo, default yes + \v!no=>\splittabulatefalse, + \v!auto=>\ifinsidefloat\ifinsidesplitfloat\else\splittabulatefalse\fi\fi]% + \doifvaluesomething{\??tt\currenttabulate\c!bodyfont} + {\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 + \tabulateparameter\c!inner + \scratchdimen\leftskip + \advance\scratchdimen \hangindent + \doifvalue{\??tt\currenttabulate\c!indenting}\v!yes + {\advance\scratchdimen \parindent}% \ctxparindent + \edef\tabulateindent{\the\scratchdimen}% + \!!toksb\emptytoks + \def\dorepeat*##1##2% + {\dorecurse{##1}{\appendtoks##2\to\!!toksb}\do}% + \def\do + {\futurelet\next\dodo}% + \def\dodo % \@EAEAEA gebruiken + {\ifx\next\relax + % exit + \else\ifx*\next + \let\next\dorepeat + \else\ifx\bgroup\next + \let\next\dododo + \else + \let\next\dodododo + \fi\fi\fi + \next}% + \def\dododo##1% + {\appendtoks{##1}\to\!!toksb\do}% + \def\dodododo##1% + {\appendtoks##1\to\!!toksb\do}% + \global\tabulatecolumn\zerocount +% \do#3\relax +\bgroup\@@useotherbar\expanded{\egroup\noexpand\do#3\relax}% + \processcontent + {\e!stop#1}% \currenttabulate} + \tabulatecontent + {\@EA\processtabulate\@EA[\the\!!toksb]}} + +\chardef\tabulatetype=0 + +% 0 = NC column next EQ equal column +% 1 = RC column raw RQ equal column raw +% 2 = HC column hook HQ equal column hook + +\newif\iftabulatefirstflushed + +\def\tabulateEQ + {\iftabulatefirstflushed\else\tabulateparameter{EQ}\fi + \global\tabulateequalfalse} + +% \def\tabulatenormalcolumn#1% +% {&\iftabulateequal\tabulateEQ\fi&\global\chardef\tabulatetype#1&} +% +% \def\tabulateequalcolumn#1% +% {&\tabulateEQ&\global\chardef\tabulatetype#1&} +% +% however, \unskip en \ignorespaces permit usage in complex XML/\starttabulate + +\def\tabulatenormalcolumn#1% + {\unskip&\iftabulateequal\tabulateEQ\fi&\global\chardef\tabulatetype#1&% + \ignorespaces} + +\def\tabulateequalcolumn#1% + {\unskip&\tabulateEQ&\global\chardef\tabulatetype#1&% + \ignorespaces} + +\def\tabulateautocolumn + {\tabulatenormalcolumn\zerocount + \ifnum\tabulatecolumn>\tabulatecolumns\relax + \expandafter\NR + \else + \expandafter\ignorespaces % interferes with the more tricky hooks + \fi} + +\def\setquicktabulate#1% see \startlegend \startgiven + {\let#1\tabulateautocolumn + \let\\\tabulateautocolumn} + +%\def\dotabulateruleseperator +% {\vskip\strutdp} + +\def\dotabulateruleseperator % can be sped up + {\bgroup + \let\factor\!!plusone + \scratchskip\strutdp + \ExpandFirstAfter\processallactionsinset + [\tabulateparameter\c!distance] + [ \v!blank=>\scratchskip\bigskipamount, + \v!depth=>\scratchskip\strutdp, + \v!small=>\def\factor{.25}, + \v!medium=>\def\factor{.5}, + \v!big=>, + \v!none=>\scratchskip\zeropoint\def\factor{0}, + \v!grid=>\scratchskip\zeropoint\def\factor{0}, + \s!unknown=>\scratchskip\commalistelement]% + \scratchdimen\factor\scratchskip + \ifconditional\tabulatesomeamble\kern\else\vskip\fi\scratchdimen % new + \egroup} + +\def\dodotabulaterule#1% + {\color + [\tabulateparameter\c!rulecolor] + {\scratchdimen\tabulateparameter\c!rulethickness#1}} + +\def\dotabulaterule + {\dodotabulaterule + {\hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen\relax + \doifvalue{\??tt\currenttabulate\c!distance}\v!grid + {\kern-\scratchdimen}}} % experimental tm-prikkels + +\def\dotabulatelinerule + {\multispan\totaltabulatecolumns % \multispan is a plain macro + % for the moment this one + \strut\hskip\tabulateparameter\c!margin + % neg values are ok ! + \hskip\tabulateindent % new august 2003 + \dodotabulaterule + {\!!heighta.5\lineheight + \advance\!!heighta-\strutdepth + \!!deptha-\!!heighta + \advance\!!deptha\scratchdimen + \leaders\hrule\!!height\!!heighta\!!depth\!!deptha\hfill}% + \cr} + +%D When set to true, no (less) break optimization is done. + +\newif\iftolerantTABLEbreak + +%D The main processing macro is large but splitting it up +%D would make things less clear. + +\def\doregistertabulateparoptions + {\iftrialtypesetting \else + \registerparoptions + \ifinsidefloat + % that is, an unbreakable one + \global\let\registertabulateparoptions\empty + \else + % unsafe in crossing pages, at each b... + % \global\let\registertabulateparoptions\empty + \fi + \fi} + +\appendtoks + \global\let\registertabulateparoptions\doregistertabulateparoptions +\to \everytabulate + +\newtoks\everytabulaterow + +\appendtoks + \registertabulateparoptions +\to \everytabulaterow + +\def\flushtabulateindent + {\ifnum\tabulatecolumn=\zerocount + \hbox to \tabulateindent + {% we now have a local hsize, and since we want to + % register positional info (i.e. real hsizes) we + % need to reconstitute the original hsize + \advance\hsize\tabulateindent + % this is indeed rather messy and took a few hours + % to dis/uncover + \the\everytabulaterow + \hss}% + \fi} + +\def\totaltabulatecolumns{0} + +\def\handletabulatedigits{\digits} + +%D Beware, we cannot use \type {\unexpanded} on \type {\HL} +%D cum suis, since \TEX's hard coded noalign lookahead fails +%D on it! I mistakenly added this for a while. + +\chardef\tabulaterepeathead\zerocount + +\newcount\noftabulatelines +\newcount\totalnoftabulatelines +\newcount\minusnoftabulatelines + +\setvalue{\??tt:\c!align:\v!normal}{0} +\setvalue{\??tt:\c!align:\v!right }{1} +\setvalue{\??tt:\c!align:\v!left }{2} +\setvalue{\??tt:\c!align:\v!middle}{3} + +\setvalue{\??tt:\c!header:\v!repeat}{\plusone} +\setvalue{\??tt:\c!header:\v!text }{\plustwo} + +\bgroup \catcode`\|=\@@other + +\gdef\processtabulate[|#1|]% in the process of optimizing + {\tabulateunit\tabulateparameter\c!unit + \checkfulltabulatecontent + \globallet\tabulateruledepth \!!zeropoint + \globallet\tabulateruleheight\!!zeropoint + \edef\@@tabulatealign{\executeifdefined{\??tt:\c!align:\tabulateparameter\c!align}0}% +% \ExpandFirstAfter\processaction % use \setalignmentswitch instead +% [\tabulateparameter\c!align] +% [ \v!normal=>\def\@@tabulatealign{0},% = default value +% \v!right=>\def\@@tabulatealign{1},% chardefs gebruiken +% \v!left=>\def\@@tabulatealign{2},% +% \v!middle=>\def\@@tabulatealign{3},% +% \s!default=>\def\@@tabulatealign{0},% +% \s!unknown=>\def\@@tabulatealign{0}]% + \let\pretabskip\!!zeropoint + \def\postabskip{.5\tabulateunit}% + \global\tabulatecolumns\zerocount + \global\nofautotabulate\zerocount + \global\noftabulatelines\zerocount + \totalnoftabulatelines\noftabulatelines + \minusnoftabulatelines\noftabulatelines + \global\tabulatepwidth\zeropoint + \global\tabulateequalfalse + \resettabulatepheight + \ifinsidesplitfloat + \donetrue + \else\ifinsidefloat + \donefalse + \else + \donetrue + \fi\fi + \ifdone + \chardef\tabulaterepeathead\executeifdefined{\??tt:\c!header:\tabulateparameter\c!header}\zerocount +% \processaction +% [\tabulateparameter\c!header] +% [\v!repeat=>\let\tabulaterepeathead\plusone, +% \v!text=>\let\tabulaterepeathead\plustwo]% + \fi + \unexpanded \def\NC{\tabulatenormalcolumn0}% + \unexpanded \def\RC{\tabulatenormalcolumn1}% + \unexpanded \def\HC{\tabulatenormalcolumn2}% + \unexpanded \def\EQ{\tabulateequalcolumn 0}% + \unexpanded \def\RQ{\tabulateequalcolumn 1}% + \unexpanded \def\HQ{\tabulateequalcolumn 2}% + \unexpanded \def\NG{\NC\handletabulatecharalign}% + \unexpanded \def\NN{\NC\handletabulatedigits}% new, undocumented, test first + \unexpanded \def\ND{\NC\handletabulatedigits}% same, for old times sake + \def\tabulaterule{\HR}% a rule with lineheight + \def\tabulateline{\HL}% just a spaced rule + \def\tabulateautorule{\doHR\plusone}% + \def\tabulateautoline{\doHL\plusone}% + \def\HR{\doHR\zerocount} + \def\HL{\doHL\zerocount} + \unexpanded \def\NR % next row + {\global\advance\noftabulatelines\plusone + \global\tabulatefirstflushedfalse + \global\tabulateequalfalse + \global\tabulatecolumn\zerocount + \resettabulatepheight + \unskip\unskip\crcr\flushtabulated + \TABLEnoalign + {\iftolerantTABLEbreak\else + \ifconditional\tabulatesomeamble \ifcase\tabulaterepeathead \else + \allowbreak + \fi \fi + \ifnum\noftabulatelines=\plusone + \dotabulatenobreak + \else\ifnum\noftabulatelines=\minusnoftabulatelines + \ifnum\tabulatemaxplines<\plustwo + \dotabulatenobreak + \else + \allowbreak % needed with pbreak prevention + \fi + \else + \allowbreak % needed with pbreak prevention + \fi\fi + \fi + \global\tabulatefirstflushedfalse}}% + \let\HL\empty % not needed + \let\SR\NR \let\AR\NR + \let\FL\empty \let\FR\NR + \let\ML\empty \let\MR\NR + \let\LL\empty \let\LR\NR + \let\doHR\gobbleoneargument + \let\doHL\gobbleoneargument + \global\let\flushtabulated\empty +% \let\savedbar|\let|\nexttabulate + \tabskip\zeropoint + \ifdim\tabulateparameter\c!margin>\zeropoint + \!!toksa{&\flushtabulateindent\strut##% + \tabskip\tabulateparameter\c!margin\strut + &##\tabskip\zeropoint}% + \else + \!!toksa{&\flushtabulateindent\strut##% + &##\tabskip\zeropoint}% + \fi + \tabulatewidth\zeropoint + % |#1X|\relax + \nexttabulate #1X|\relax + \scratchcounter\tabulatecolumns + \multiply\scratchcounter3% + \advance\scratchcounter4% + \edef\totaltabulatecolumns{\the\scratchcounter}% + \tabulatewidth\zeropoint + % \dorecurse\tabulatecolumns % can be made faster + % {\doifundefinedelse{\@@tabbox@@\recurselevel} + % {\expandafter\newbox\csname\@@tabbox@@\recurselevel\endcsname}% + % {\global\setbox\csname\@@tabbox@@\recurselevel\endcsname\emptybox}}% + \initializetableboxes\tabulatecolumns + \appendtoks&##\to\!!toksa + \appendtoks\global\advance\tabulatecolumn\plusone\to\!!toksa + \appendtoks\NC\unskip\unskip\crcr\flushtabulated\to\tabulatedummy % no count + \global\tabulatecolumn\zerocount + \resettabulatepheight + \def\bskip + {\setbox\tabulatebox\vbox\bgroup + \global\let\tabulatehook\notabulatehook}% + \def\eskip + {\par\egroup + \global\let\tabulatehook\dotabulatehook}% + \def\xbskip + {\hbox\bgroup\vbox\bgroup + \global\let\tabulatehook\notabulatehook}% + \def\xeskip + {\par\egroup\egroup + \global\let\tabulatehook\dotabulatehook}% + % \let|\savedbar + \global\let\tabulatehook\dotabulatehook + \doifvalue{\??tt\currenttabulate\c!indenting}\v!no\forgetparindent + \ifinsidefloat + \let\tabulateindent\!!zeropoint + \else + \setlocalhsize \hsize\localhsize + \fi + \dontcomplain + \forgetall % hm, interference with \forgetparindent ^^^ probably bug, to be solved + \setbox0\vbox % outside \if because of line counting + {\notesenabledfalse + \let\tabulateindent\!!zeropoint + \trialtypesettingtrue % very important + \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}}% + \ifnum\nofautotabulate>\zerocount + % so, even if the natural size is larger, in the final + % run, we force the calculated width + \tabulatewidth\hsize + \advance\tabulatewidth -\wd0 + \advance\tabulatewidth -\tabulatepwidth + \ifnum\nofautotabulate>\zerocount + \divide\tabulatewidth \nofautotabulate\relax + \fi + \fi + \def\xbskip{\bskip}% + \def\xeskip{\eskip}% + \ifsplittabulate + \splittopskip\strutht + \global\let\flushtabulatedindeed\empty + \long\def\bbskip + {\ifvoid\tablebox\tabulatecolumn + \ifx\flushtabulatedindeed\empty\else + \setbox0\hbox + \fi + \fi}% + \def\bskip + {\ifvoid\tablebox\tabulatecolumn + \global\setbox\tablebox\tabulatecolumn\vbox + \bgroup + \global\let\tabulatehook\notabulatehook + \ifautotabulate\hsize\tabulatewidth\fi + % \begstrut % interferes with pre-\pars + % evt: \appendtoks\begstrut\to\everypar + \ignorespaces + \def\eskip + {\par\egroup + \settabulatepheight + \global\let\tabulatehook\dotabulatehook + \splitofftabulatebox}% + \else + \let\eskip\empty + \dontcomplain + \global\let\tabulatehook\dotabulatehook + \expandafter\splitofftabulatebox + \fi}% + \gdef\flushtabulated + {\TABLEnoalign % noalign % no interference ! + {\global\let\flushtabulatedindeed\empty + \global\tabulatecolumn\zerocount + \handletabulatepbreak + \dorecurse\tabulatecolumns % was: \noftabcolumns + {\ifvoid\tablebox\recurselevel\else + \gdef\flushtabulatedindeed{\the\tabulatedummy}% + \fi}% + \global\tabulatefirstflushedtrue}% + \flushtabulatedindeed}% + \else + % tabhook op alles ? + \def\bskip + {\vtop\bgroup + \ifautotabulate\hsize\tabulatewidth\fi + % \begstrut % interferes with pre-\pars + % evt: \appendtoks\begstrut\to\everypar + \ignorespaces}% + \def\eskip % vertical strut added august 2003 + {\par\verticalstrut\vskip-\struttotal\egroup}% + \fi + \totalnoftabulatelines\noftabulatelines + \minusnoftabulatelines\numexpr\noftabulatelines+\minusone\relax + \global\noftabulatelines\zerocount + \def\doHL##1% ##1 ignored + {\TABLEnoalign + {\csname + \ifnum\noftabulatelines=\zerocount F\else + \ifnum\noftabulatelines=\totalnoftabulatelines L\else + M\fi\fi + L\endcsname}}% + \def\doHR##1% horizontal rule line (break untested) + {\TABLEnoalign + {\globallet\TABLEautoline\dotabulatelinerule + \ifcase##1\or + \ifnum\noftabulatelines=\zerocount + \gdef\TABLEautoline{\TABLEnoalign{}}% + \else\ifnum\noftabulatelines=\totalnoftabulatelines + \gdef\TABLEautoline{\TABLEnoalign{}}% + \fi\fi + \fi + \dotabulatenobreak}% + \TABLEautoline + \TABLEnoalign + {\nobreak + \ifx\TABLEautoline\dotabulatelinerule\kern-\lineheight\fi + \ifnum\noftabulatelines=\totalnoftabulatelines + \@EA\dotabulatenobreak + \else + \@EA\allowbreak + \fi}% + \TABLEautoline + \TABLEnoalign + {\dotabulatenobreak}}% + \doifelsevalue{\??tt\currenttabulate\c!rule}\v!line + {\let\HL \HR + \let\tabulateautoline\tabulateautorule + \let\tabulateline \tabulaterule}% + {\def\HL{\doHL\zerocount}}% + \def\tablebaselinecorrection + {\def\dobaselinecorrection + {\vskip-\prevdepth + \vskip\strutdp + \vskip\strutdp}% + \baselinecorrection}% + \def\FL{\TABLEnoalign + {\ifinsidefloat\else + \doifemptyvalue{\??tt\currenttabulate\c!before} % no expansion + {\tablebaselinecorrection}% + \fi + \dotabulaterule + \dotabulatenobreak + \dotabulateruleseperator + \prevdepth\strutdp + \dotabulatenobreak}}% + \def\ML{\TABLEnoalign + {\dotabulateruleseperator + \dotabulaterule + \ifnum\noftabulatelines>\plusone + \ifnum\noftabulatelines<\minusnoftabulatelines + \vskip\topskip\allowbreak\vskip-\topskip + \vskip-\tabulateparameter\c!rulethickness + \dotabulaterule + \fi + \fi + \dotabulateruleseperator}}% + \def\LL{\TABLEnoalign + {\dotabulatenobreak + \dotabulateruleseperator + \dotabulatenobreak + \dotabulaterule + \ifinsidefloat\else + \doifemptyvalue{\??tt\currenttabulate\c!after} % no expansion + {\vskip\strutdp + \verticalstrut + \vskip-\struttotal}% + \fi}}% + \let\tabulatepass\plustwo + % + \ifcase\tabulaterepeathead + \ifinsidesplitfloat + \setbox\tabulatebox\vbox \bgroup + \else + \startframedcontent[\tabulateparameter\c!frame]% + \fi + \else + \setbox\tabulatebox\vbox \bgroup + \fi + % + \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}% + \prevdepth\strutdp % nog eens beter, temporary hack + \doifvalue{\??tt\currenttabulate\c!distance}\v!grid + {\vskip-\strutdp}% experimental tm-prikkels + % + \ifcase\tabulaterepeathead + \ifinsidesplitfloat + \egroup \splittabulatebox\tabulatebox + \else + \stopframedcontent + \fi + \else + \egroup \splittabulatebox\tabulatebox + \fi + % + \egroup + \ifinsidefloat \else + \tabulateparameter\c!after + \fi + \egroup} + +\egroup + +% \setuptabulate[split=yes,header=text,title=Vervolg van Tabel] +% +% % \starttabulatehead +% % \NC test \NC hans\NC \NR +% % \stoptabulatehead +% +% \starttabulate +% \NC test \NC \input tufte \relax \NC \NR +% \NC test \NC \input knuth \relax \NC \NR +% \NC test \NC \input knuth \relax \NC \NR +% \NC test \NC \input tufte \relax \NC \NR +% \NC test \NC \input tufte \relax \NC \NR +% \NC test \NC \input tufte \relax \NC \NR +% \stoptabulate + +% \def\splittabulatebox#1% #1 <> 0/2 / derived from the one in core-ntb.tex +% {\ifinsidefloat +% \unvbox#1% +% \else +% \ifcase\tabulaterepeathead\or +% \setbox2\copy#1% +% \setbox2\vsplit2 to \lineheight +% \setbox2\vbox{\unvbox2}% +% \fi +% \doloop +% {\setbox0\vsplit#1 to \onepoint % \lineheight +% \ifdim\pagegoal<\maxdimen +% \donetrue +% \else\ifdim\pagetotal=\zeropoint +% \donetrue +% \else +% \donefalse +% \fi\fi +% \ifdone +% \setbox0\vbox{\unvbox0}% +% \dimen0\pagetotal +% \advance\dimen0\dp0 +% \advance\dimen0\ht0 +% \ifdim\dimen0>\pagegoal +% \bgroup \page \egroup % make sure that local vars are kept +% \ifcase\tabulaterepeathead\or +% \unvcopy2 +% \or +% \hbox{\strut\tabulateparameter\c!title}% +% \fi +% \fi +% \fi +% % test this on icare checklists / quite hacky ! ! ! +% \ifdim\ht0>\tabulateparameter\c!rulethickness\else +% \kern-2\ht0 % brrrr +% \fi +% % +% \unvbox0 +% \allowbreak +% \ifvoid#1 \exitloop \fi}% +% \fi} + +\def\splittabulatebox#1% #1 <> 0/2 / derived from the one in core-ntb.tex + {\ifinsidesplitfloat + \dosplittabulatebox#1% + \else\ifinsidefloat + \unvbox#1% + \else + \dosplittabulatebox#1% + \fi\fi} + +\def\dosplittabulatebox#1% + {\resettsplit + \def\tsplitminimumfreelines{2}% + \def\tsplitminimumfreespace{0pt}% + \setbox\tsplitcontent\box#1% + \ifcase\tabulaterepeathead\or + \setbox\tsplithead\vsplit\tsplitcontent to \lineheight + \setbox\tsplithead\vbox{\unvbox\tsplithead}% + \or + \setbox\tsplithead\vbox{\hbox{\strut\tabulateparameter\c!title}}% + \fi + \handletsplit} + +%D \starttyping +%D \setuptabulate[split=no,rule=line] +%D +%D \starttabulate +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \NC tufte \NC \input tufte \NC \NR \tabulateautorule +%D \stoptabulate +%D \stoptyping + +% \starttabulatie[|mc|] +% \NC \digits{100.000,00} \NC\NR +% \NC \digits{@10.000,00} \NC\NR +% \NC \digits{@@@.100,00} \NC\NR +% \NC \digits{@@@.@10,@@} \NC\NR +% \NC \digits{@@@.@@1,@@} \NC\NR +% \stoptabulatie +% +% \starttabulatie[|mc|] +% \ND 100.000,00 \NC\NR +% \ND @10.000,00 \NC\NR +% \ND @@@.100,00 \NC\NR +% \ND @@@.@10,@@ \NC\NR +% \ND @@@.@@1,@@ \NC\NR +% \stoptabulatie +% +% \starttabulatie[|c|] +% \ND $100.000,00$ \NC\NR +% \ND $@10.000,00$ \NC\NR +% \ND $@@@.100,00$ \NC\NR +% \ND $@@@.@10,@@$ \NC\NR +% \ND $@@@.@@1,@@$ \NC\NR +% \stoptabulatie +% +% \starttabulatie[|c|] +% \NC $\digits 100.000,00 $ \NC\NR +% \NC $\digits @10.000,00 $ \NC\NR +% \NC $\digits @@@.100,00 $ \NC\NR +% \NC $\digits @@@.@10,@@ $ \NC\NR +% \NC $\digits @@@.@@1,@@ $ \NC\NR +% \stoptabulatie +% +% \starttabulatie[|c|] +% \NC \digits $100.000,00$ \NC\NR +% \NC \digits $@10.000,00$ \NC\NR +% \NC \digits $@@@.100,00$ \NC\NR +% \NC \digits $@@@.@10,@@$ \NC\NR +% \NC \digits $@@@.@@1,@@$ \NC\NR +% \stoptabulatie + +\def\setuptabulate + {\dotripleempty\dosetuptabulate} + +\def\dosetuptabulate[#1][#2][#3]% + {\ifthirdargument + \getparameters[\??tt#1::#2][#3]% + \else\ifsecondargument + \getparameters[\??tt#1::][#2]% + \else + \getparameters[\??tt\v!tabulate::][#1]% + \fi\fi} + +\setuptabulate + [\c!unit=1em, + EQ={:}, + \c!frame=\v!off, + \c!bodyfont=, + \c!rule=\v!normal, + \c!rulecolor=, + \c!rulethickness=\linewidth, + \c!inner=, + \c!before=\blank, + \c!after=\blank, + \c!distance={\v!depth,\v!medium}, + \c!align=\v!normal, + \c!margin=\!!zeropoint, + \c!split=\v!auto, + \c!header=\v!yes, + \c!title=, + \c!indenting=\v!no] + +\protect \endinput diff --git a/tex/context/base/tabl-tsp.tex b/tex/context/base/tabl-tsp.tex new file mode 100644 index 000000000..49bb7ad90 --- /dev/null +++ b/tex/context/base/tabl-tsp.tex @@ -0,0 +1,427 @@ +%D \module +%D [ file=tabl-tsp, +%D version=2000.10.20, +%D title=\CONTEXT\ Table Macros, +%D subtitle=Splitting, +%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 Table Macros / Splitting} + +%D The code in this file is move here from other places. + +\unprotect + +% only to be used with single tokens (will be prim) + +\ifx\htdp\undefined \def\htdp#1{\dimexpr\ht#1+\dp#1\relax} \fi + +%D Although the name resembles floats, and therefore this should be +%D a page module, we decided to make it core functionality because the +%D table code depends on it. Othrwise there would be too much +%D overloading afterwards involved. Actually, the float part is rather +%D generic and not that related to floats. + +% \splitfloat [settings] {\placetable[optional args]{test}} {content} + +\definenumber + [\??si] + [\c!way=\v!by\v!text, + \c!conversion=\@@siconversion] + +\def\setupfloatsplitting + {\dodoubleargument\getparameters[\??si]} + +\newif\ifinsidesplitfloat % will become chardef + +\newtoks \everysplitfloatsetup + +\def\splitfloat + {\dosingleempty\dosplitfloat} + +\ifx\floatcaptionsuffix\undefined \else + \let\floatcaptionsuffix\empty % will become \splitfloatcaptionsuffix +\fi + +\def\extrasplitfloatlines{0} + +\def\dosplitfloat[#1]#2% nog dubbele refs + {\bgroup + \global\setfalse\splitfloatdone + \aftergroup\checksplitfloat + \insidefloattrue + \insidesplitfloattrue + \getparameters[\??si][#1]% + \resetnumber[\??si]% + \def\floatcaptionsuffix{\convertednumber[\??si]}% + \let\extrasplitfloatlines\@@silines + \the\everysplitfloatsetup + \def\splitfloatcommand{#2}% + \global\settrue \onlyonesplitofffloat + \global\setfalse\somenextplitofffloat + \dopushsavedfloats + \@@sibefore + \let\next} % \bgroup + +\def\checksplitfloat + {\ifconditional\splitfloatdone\else + \blank{\tttf \getmessage\m!floatblocks{13}\empty}\blank + \showmessage\m!floatblocks{13}\empty + \fi} + +\settrue \onlyonesplitofffloat +\setfalse\somenextplitofffloat + +%D When \type {inbetween} is made empty instead of the +%D default \type {\page}, we will get delayed flushing +%D and text may continue below the graphic. +%D +%D \starttyping +%D \dorecurse{2}{\input tufte } +%D +%D \splitfloat[lines=auto,inbetween=] +%D {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}} +%D {\bTABLE[split=yes] +%D \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR +%D \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR +%D \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR +%D \bTR \bTD 14 \eTD \bTD test \eTD \eTR +%D \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR +%D \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR +%D \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR +%D \bTR \bTD 24 \eTD \bTD test \eTD \eTR +%D \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR +%D \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR +%D \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR +%D \bTR \bTD 34 \eTD \bTD test \eTD \eTR +%D \eTABLE} +%D +%D \dorecurse{10}{\input tufte } +%D \stoptyping + +\newconditional\splitfloatdone + +\def\dodowithsplitofffloat + {\dowithnextbox + {\forgetall + \dontcomplain + \global\settrue\splitfloatdone + \chardef\nodelocationmode\zerocount % bypass auto-renumbering + \incrementnumber[\??si]% + \ifcase\rawnumber[\??si]\or \ifconditional\onlyonesplitofffloat + \let\floatcaptionsuffix\empty + \fi \fi + \bgroup + \ifconditional\somenextplitofffloat + \settrue\retainfloatnumber +\notesenabledfalse % best here, experimental, brrr; test with note in caption + \else + \setfalse\retainfloatnumber + \fi + \splitfloatcommand{\box\nextbox}% + \egroup + \ifconditional\somenextplitofffloat + \doifelsenothing\@@siinbetween + {\ifconditional\splitfloatfirstdone\else\page\fi} + \@@siinbetween + \else + \@@siafter + \dopopsavedfloats + \doflushsavedfloats + \fi + \global\settrue\splitfloatfirstdone}% + \vbox} + +\def\nodowithsplitofffloat + {\dowithnextbox + {\forgetall + \dontcomplain + \box\nextbox % maybe an option to unvbox + \global\settrue\splitfloatfirstdone}% + \vbox} + +\def\dochecksplitofffloat#1% box + {\ifinsidesplitfloat + \ifdim\ht#1=\zeropoint + \global\setfalse\somenextplitofffloat + \else + \global\settrue \somenextplitofffloat + \global\setfalse\onlyonesplitofffloat + \fi + \fi} + +\def\analyzesplitfloatcaption#1% depends on page-flt + {\doif\extrasplitfloatlines\v!auto + {\bgroup + \settrue\retainfloatnumber + \chardef\nodelocationmode\zerocount + \forcelocalfloats + \setuplocalfloats[\c!before=,\c!after=,\c!inbetween=]% + \splitfloatcommand{\hbox to \wd#1{\strut}}% dummy line + \setbox\scratchbox\vbox{\flushlocalfloats}% + \getnoflines{\ht\scratchbox}% + \resetlocalfloats + \advance\noflines\minusone % compensate dummy line + \expanded{\egroup\noexpand\edef\noexpand\extrasplitfloatlines{\the\noflines}}}} + +% \def\analyzesplitfloatcaption#1% +% {\edef\extrasplitfloatlines{11}} + +\def\dowithsplitofffloat % nextbox + {\ifinsidesplitfloat + \expandafter\dodowithsplitofffloat + \else + \expandafter\nodowithsplitofffloat + \fi} + +\def\doifnotinsidesplitfloat + {\ifinsidesplitfloat\expandafter\gobbleoneargument\fi} + +%D Some defaults: + +\setupfloatsplitting + [\c!conversion=\v!character, % \v!romannumerals + \c!lines=3, + \c!before=, + \c!inbetween=\page, + \c!after=] + +%D Table splitter, on top of previous code: + +\newbox\tsplitcontent +\newbox\tsplitresult +\newbox\tsplithead +\newbox\tsplitnext +\newbox\tsplittail + +\def\resettsplit{% only \def's starting a a new line are seen by the dep checker + \def\tsplitminimumfreelines{0}% + \def\tsplitminimumfreespace{0pt}% + \setbox\tsplitcontent \vbox{}% + \setbox\tsplitresult \vbox{}% + \setbox\tsplithead \vbox{}% + \setbox\tsplitnext \vbox{}% + \setbox\tsplittail \vbox{}% + \let\tsplitbeforeresult\donothing + \let\tsplitafterresult \donothing + \let\tsplitinbetween \donothing + \let\tsplitbefore \donothing + \let\tsplitafter \donothing + \let\postprocesstsplit \donothing +} + +\resettsplit + +% todo: keep tail to rest, so we need a lookahead + +\newconditional\splitfloatfirstdone + +\def\handletsplit + {\analyzesplitfloatcaption\tsplitcontent + \global\setfalse\splitfloatfirstdone + \testpagesync % new, sync, but still tricky + [\tsplitminimumfreelines] + [\dimexpr\tsplitminimumfreespace+\extrasplitfloatlines\lineheight\relax]% + \setbox\scratchbox\vbox{\tsplitinbetween}% + \edef\tsplitinbetweenheight{\the\htdp\scratchbox}% etex + \!!doneafalse + \doloop + {\ifinsidecolumns + % brrr, assumes empty columns + \global\setfalse\splitfloatfirstdone + \scratchdimen\textheight + \!!donectrue + \else + \ifconditional\splitfloatfirstdone + \scratchdimen\textheight + \!!donectrue + \else\ifdim\pagegoal<\maxdimen + \scratchdimen\dimexpr\pagegoal-\pagetotal\relax + \!!donecfalse + \else + \scratchdimen\textheight + \!!donectrue + \fi\fi + \fi + \scratchdimen\dimexpr\scratchdimen-\tsplitinbetweenheight-\tsplitminimumfreespace-\extrasplitfloatlines\lineheight\relax + \ifdim\htdp\tsplittail>\zeropoint + \advance\scratchdimen-\htdp\tsplittail + \fi + \setbox\tsplitresult\vbox + {\ifdim\ht\tsplithead>\zeropoint + \unvcopy\tsplithead + \tsplitinbetween + \fi}% + \if!!donea\else\ifdim\ht\tsplitnext>\zeropoint + \setbox\tsplithead\box\tsplitnext + \fi\fi + \!!doneatrue + \ifdim\ht\tsplitresult>\zeropoint + \!!donedtrue % table head + \else + \!!donedfalse % no tablehead + \fi + \splittopskip\zeropoint + \doloop + {\setbox\scratchbox\vsplit\tsplitcontent to \onepoint % \lineheight + \setbox\scratchbox\vbox{\unvbox\scratchbox}% + \ifdim\dimexpr\scratchdimen-\htdp\scratchbox-\htdp\tsplitresult\relax>\zeropoint + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvbox\scratchbox}% + \ifvoid\tsplitcontent \exitloop \fi + \else\if!!doned + % we only have a tablehead so far + \setbox\tsplitresult\vbox{\unvbox\tsplitresult\unvbox\scratchbox}% + \exitloop + \else\if!!donec + % we have text height available, but the (one) cell is too + % large to fit, so, in order to avoid loops/deadcycles we do: + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvbox\scratchbox}% + \exitloop + \else + \setbox\tsplitcontent\vbox + {\unvbox\scratchbox + \tsplitinbetween + \ifvoid\tsplitcontent\else\unvbox\tsplitcontent\fi}% + \exitloop + \fi\fi\fi + \!!donedfalse + \!!donecfalse}% + \postprocesstsplit + \dochecksplitofffloat\tsplitcontent + \ifvoid\tsplitcontent + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvcopy\tsplittail}% + \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% + \doifnotinsidesplitfloat\tsplitafter + \endgraf + \exitloop + \else + % hack + \ifdim\pagegoal<\maxdimen + \global\pagegoal\dimexpr\pagegoal+\lineheight\relax % etex + \fi + % brrr + \ifdim\ht\tsplitresult>\zeropoint + \setbox\tsplitresult\vbox + {\unvbox\tsplitresult + \tsplitinbetween + \unvcopy\tsplittail}% + \dowithsplitofffloat{\tsplitbeforeresult\box\tsplitresult\tsplitafterresult}% + \doifnotinsidesplitfloat\tsplitafter + \endgraf + \fi + \ifinsidecolumns + \doifnotinsidesplitfloat\goodbreak + \else + \doifnotinsidesplitfloat\page + \fi + \fi}% + \global\setfalse\splitfloatfirstdone} % we can use this one for tests + +\protect \endinput + +% test cases + +% \setupTABLE[split=repeat] +% +% \input tufte \endgraf +% \splitfloat[lines=11] +% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} +% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE} +% \input tufte \page +% +% \input tufte \endgraf +% \splitfloat[lines=0] +% {} +% {\bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE} +% \input tufte \endgraf \page +% +% \input tufte \endgraf +% \bTABLE\dorecurse{100}{\bTR \bTD test \eTD \eTR}\eTABLE +% \input tufte \page + +% \setuptabulate[split=yes] +% +% \input tufte \endgraf +% \splitfloat[lines=11] +% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} +% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate} +% \input tufte \page +% +% \input tufte \endgraf +% \splitfloat[lines=0] +% {} +% {\starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate} +% \input tufte \page +% +% \input tufte \endgraf +% \starttabulate\dorecurse{200}{\NC test \NC test \NC \NR}\stoptabulate +% \input tufte \page + +% \setuptables[split=yes] +% +% \newtoks\TestToks +% +% \TestToks\emptytoks +% \appendtoks\starttablehead\to\TestToks +% \dorecurse{3}{\appendtoks\VL head \VL head \VL \SR\to\TestToks} +% \appendtoks\stoptablehead\to\TestToks +% \appendtoks\starttabletail\to\TestToks +% \dorecurse{3}{\appendtoks\VL tail \VL tail \VL \SR\to\TestToks} +% \appendtoks\stoptabletail\to\TestToks +% \appendtoks\starttables[|c|c|]\to\TestToks +% \dorecurse{100}{\appendtoks\VL test \VL test \VL \SR\to\TestToks} +% \appendtoks\stoptables\to\TestToks +% +% \input tufte \endgraf +% \splitfloat[lines=auto] % [lines=11] +% {\placetable{\dorecurse{10}{test\recurselevel\endgraf}}} +% {\the\TestToks} +% \input tufte \page +% +% \input tufte \endgraf +% \splitfloat[lines=0] +% {} +% {\the\TestToks} +% \input tufte \page +% +% \input tufte \endgraf +% \the\TestToks +% \input tufte \page +% +% multiple floats +% +% \starttext +% \dorecurse{3}{\input tufte } \endgraf +% \dorecurse{5}{\placefigure{}{\framed[height=.5\textheight]{}}} +% \splitfloat[lines=auto,inbetween=] +% {\placetable{\dorecurse{5}{test\recurselevel\endgraf}}} +% {\bTABLE[split=yes] +% \bTR \bTD 11 \eTD \bTD \input tufte \eTD \eTR +% \bTR \bTD 12 \eTD \bTD \input zapf \eTD \eTR +% \bTR \bTD 13 \eTD \bTD \input bryson \eTD \eTR +% \bTR \bTD 14 \eTD \bTD test \eTD \eTR +% \bTR \bTD 21 \eTD \bTD \input tufte \eTD \eTR +% \bTR \bTD 22 \eTD \bTD \input zapf \eTD \eTR +% \bTR \bTD 23 \eTD \bTD \input bryson \eTD \eTR +% \bTR \bTD 24 \eTD \bTD test \eTD \eTR +% \bTR \bTD 31 \eTD \bTD \input tufte \eTD \eTR +% \bTR \bTD 32 \eTD \bTD \input zapf \eTD \eTR +% \bTR \bTD 33 \eTD \bTD \input bryson \eTD \eTR +% \bTR \bTD 34 \eTD \bTD test \eTD \eTR +% \eTABLE} +% \dorecurse{10}{\input tufte } +% \stoptext 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 spans the next 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-- -

This code is experimental.

+

This code is experimental and needs a cleanup. The visualizers will move to +a module.

--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/trac-deb.lua b/tex/context/base/trac-deb.lua new file mode 100644 index 000000000..f476169c3 --- /dev/null +++ b/tex/context/base/trac-deb.lua @@ -0,0 +1,206 @@ +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 lmx then lmx = { } end +if not lmx.variables then lmx.variables = { } end + +lmx.variables['color-background-green'] = '#4F6F6F' +lmx.variables['color-background-blue'] = '#6F6F8F' +lmx.variables['color-background-yellow'] = '#8F8F6F' +lmx.variables['color-background-purple'] = '#8F6F8F' + +lmx.variables['color-background-body'] = '#808080' +lmx.variables['color-background-main'] = '#3F3F3F' +lmx.variables['color-background-one'] = lmx.variables['color-background-green'] +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 + +tracers.strings.undefined = "undefined" + +function tracers.split(csname) + return csname:match("^(.+):(.+)$") +end + +function tracers.type(csname) + tag, name = tracers.split(csname) + if tag then return tag else return nil end +end + +function tracers.name(csname) + tag, name = tracers.split(csname) + if tag then return name else return csname end +end + +function tracers.cs(csname) + tag, name = tracers.split(csname) + if tracers.types[tag] then + return tracers.types[tag](name) + else + return tracers.primitive(csname) + end +end + +function tracers.dimen(name) + return (tex.dimen[name] and number.topoints(tex.dimen[name])) or tracers.strings.undefined +end + +function tracers.count(name) + return tex.count[name] or tracers.strings.undefined +end + +function tracers.toks(name) + return (tex.toks[name] and string.limit(tex.toks[name],40)) or tracers.strings.undefined +end + +function tracers.primitive(name) + return tex[name] or tracers.strings.undefined +end + +tracers.types = { + ['d'] = tracers.dimen, + ['c'] = tracers.count, + ['t'] = tracers.toks, + ['p'] = tracers.primitive +} + +function tracers.knownlist(name) + return tracers.list[name] and #tracers.list[name] > 0 +end + +function tracers.showdebuginfo() + lmx.set('title', 'ConTeXt Debug Information') + lmx.set('color-background-one', lmx.get('color-background-green')) + lmx.set('color-background-two', lmx.get('color-background-blue')) + lmx.show('context-debug.lmx') + lmx.restore() +end + +function tracers.showerror() + lmx.set('title', 'ConTeXt Error Information') + lmx.set('errormessage', status.lasterrorstring) + lmx.set('linenumber', status.linenumber) + lmx.set('color-background-one', lmx.get('color-background-yellow')) + lmx.set('color-background-two', lmx.get('color-background-purple')) + local filename = status.filename + local linenumber = tonumber(status.linenumber or "0") + if not filename then + lmx.set('filename', 'unknown') + lmx.set('errorcontext', 'error in filename') + elseif type(filename) == "number" then + lmx.set('filename', "") + lmx.set('errorcontext', 'unknown error') + elseif io.exists(filename) then + -- todo: use an input opener so that we also catch utf16 an reencoding + lmx.set('filename', filename) + lines = io.lines(filename) + if lines then + local context = { } + n, m = 1, linenumber + b, e = m-10, m+10 + s = string.len(tostring(e)) + for line in lines do + if n > e then + break + elseif n > b then + if n == m then + context[#context+1] = string.format("%" .. s .. "d",n) .. " >> " .. line + else + context[#context+1] = string.format("%" .. s .. "d",n) .. " " .. line + end + end + n = n + 1 + end + lmx.set('errorcontext', table.concat(context,"\n")) + else + lmx.set('errorcontext', "") + end + else + lmx.set('filename', filename) + lmx.set('errorcontext', 'file not found') + end + lmx.show('context-error.lmx') + lmx.restore() +end + +function tracers.overloaderror() + callback.register('show_error_hook', tracers.showerror) +end + +tracers.list['scratch'] = { + 0, 2, 4, 6, 8 +} + +tracers.list['internals'] = { + 'p:hsize', 'p:parindent', 'p:leftskip','p:rightskip', + 'p:vsize', 'p:parskip', 'p:baselineskip', 'p:lineskip', 'p:topskip' +} + +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/trac-deb.tex b/tex/context/base/trac-deb.tex new file mode 100644 index 000000000..870c452ad --- /dev/null +++ b/tex/context/base/trac-deb.tex @@ -0,0 +1,43 @@ +%D \module +%D [ file=trac-deb, +%D version=2005.11.06, +%D title=\CONTEXT\ Tracing Macros, +%D subtitle=Debugger, +%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 Tracing Macros / Debugger} + +\registerctxluafile{trac-deb}{1.001} + +\def\showdebuginfo{\ctxlua{tracers.showdebuginfo()}} +\def\overloaderror{\ctxlua{tracers.overloaderror()}} + +\def\breakpoint{\showdebuginfo\wait} + +\appendtoks + \ctxlua { + if debugger.tracing() then + debugger.enable() ; + end + }% +\to \everyjob + +\appendtoks + \ctxlua { + if debugger.tracing() then + debugger.disable() ; + debugger.savestats("\jobname-luacalls.log") ; + end + }% +\to \everybye + +\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/trac-lmx.lua b/tex/context/base/trac-lmx.lua new file mode 100644 index 000000000..07f5ae291 --- /dev/null +++ b/tex/context/base/trac-lmx.lua @@ -0,0 +1,158 @@ +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" +} + +local gsub, format, concat = string.gsub, string.format, table.concat + +-- we can now use l-xml, and we can also use lpeg + +lmx = lmx or { } + +lmx.escapes = { + ['&'] = '&', + ['<'] = '<', + ['>'] = '>', + ['"'] = '"' +} + +-- local function p -> ends up in lmx.p, so we need to cast + +lmx.variables = { } + +lmx.variables['title-default'] = 'LMX File' +lmx.variables['title'] = lmx.variables['title-default'] + +-- demonstrates: local, *all, gsub using tables, nil or value, loadstring + +function lmx.loadedfile(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 = 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) + str = tostring(str) + str = gsub(str,'&','&') + str = gsub(str,'[<>"]',lmx.escapes) + return str + end + function lmx.type(str) + if str then lmx.print("" .. lmx.escape(str) .. "") end + end + function lmx.pv(str) + lmx.print(lmx.variable(str)) + end + function lmx.tv(str) + lmx.type(lmx.variable(str)) + end + data = gsub(data,"<%?lmx%-include%s+(.-)%s-%?>", function(filename) + return lmx.loadedfile(filename) + end) + local definitions = { } + data = gsub(data,"<%?lmx%-define%-begin%s+(%S-)%s-%?>(.-)<%?lmx%-define%-end%s-%?>", function(tag,content) + definitions[tag] = content + return "" + end) + data = gsub(data,"<%?lmx%-resolve%s+(%S-)%s-%?>", function(tag) + return definitions[tag] or "" + end) + data = gsub(data,"%c%s-(<%?lua .-%?>)%s-%c", function(lua) + return "\n" .. lua .. " " + end) + data = gsub(data .. "","(.-)<%?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 + 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 + +if os.platform == "windows" then + lmx.popupfile = function(filename) os.execute("start " .. filename) end +else + lmx.popupfile = function(filename) os.execute(filename) end +end + +function lmx.make(name) + local lmxfile = lmx.lmxfile(name) + local htmfile = lmx.htmfile(name) + if lmxfile == htmfile then + 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 + +lmx.restorables = { } + +function lmx.set(key, value) + if not lmx.restorables[key] then + table.insert(lmx.restorables, key) + lmx.variables['@@' .. key] = lmx.variables[key] + end + lmx.variables[key] = value +end + +function lmx.get(key) + return lmx.variables[key] or "" +end + +function lmx.restore() + for _,key in pairs(lmx.restorables) do + lmx.variables[key] = lmx.variables['@@' .. key] + end + lmx.restorables = { } +end + +-- command line + +if arg then + if arg[1] == "--show" then if arg[2] then lmx.show (arg[2]) end + elseif arg[1] == "--convert" then if arg[2] then lmx.convert(arg[2], arg[3] or "temp.html") end + end +end diff --git a/tex/context/base/trac-lmx.tex b/tex/context/base/trac-lmx.tex new file mode 100644 index 000000000..a47d2b8bb --- /dev/null +++ b/tex/context/base/trac-lmx.tex @@ -0,0 +1,16 @@ +%D \module +%D [ file=trac-lmx, +%D version=2005.09.02, +%D title=\CONTEXT\ Tracing Macros, +%D subtitle=LMX, +%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 Tracing Macros / LMX} + +\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-- +

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 structured file. Actually, any logging that +is hooked into callbacks will be \XML\ by default.

+--ldx]]-- + +logs = logs or { } +logs.xml = logs.xml or { } +logs.tex = logs.tex or { } + +--[[ldx-- +

This looks pretty ugly but we need to speed things up a bit.

+--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("%s",category,format(fmt,...))) + else + write_nl(format("",category)) + end +end +function logs.xml.line(fmt,...) -- new + if fmt then + write_nl(format("%s",format(fmt,...))) + else + write_nl("") + 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("") end end +function logs.xml.push () if logs.level > 0 then tw("" ) end end + +function logs.xml.start_run() + write_nl("") + write_nl("") -- xmlns='www.pragma-ade.com/luatex/schemas/context-job.rng' + write_nl("") +end + +function logs.xml.stop_run() + write_nl("") +end + +function logs.xml.start_page_number() + write_nl(format("

") + write_nl("") +end + +function logs.xml.report_output_pages(p,b) + write_nl(format("", p)) + write_nl(format("", b)) + write_nl("") +end + +function logs.xml.report_output_log() +end + +function logs.xml.report_tex_stat(k,v) + texiowrite_nl("log",""..tostring(v).."") +end + +local level = 0 + +function logs.xml.show_open(name) + level = level + 1 + texiowrite_nl(format("",level,name)) +end + +function logs.xml.show_close(name) + texiowrite(" ") + level = level - 1 +end + +function logs.xml.show_load(name) + texiowrite_nl(format("",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: + 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/trac-tra.lua b/tex/context/base/trac-tra.lua new file mode 100644 index 000000000..8a51d33b9 --- /dev/null +++ b/tex/context/base/trac-tra.lua @@ -0,0 +1,221 @@ +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 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) + +debugger = debugger or { } + +local counters = { } +local names = { } +local getinfo = debug.getinfo +local format, find, lower, gmatch = string.format, string.find, string.lower, string.gmatch + +-- one + +local function hook() + local f = getinfo(2,"f").func + local n = getinfo(2,"Sn") +-- if n.what == "C" and n.name then print (n.namewhat .. ': ' .. n.name) end + if f then + local cf = counters[f] + if cf == nil then + counters[f] = 1 + names[f] = n + else + counters[f] = cf + 1 + end + end +end +local function getname(func) + local n = names[func] + if n then + if n.what == "C" then + return n.name or '' + else + -- source short_src linedefined what name namewhat nups func + local name = n.name or n.namewhat or n.what + if not name or name == "" then name = "?" end + return format("%s : %s : %s", n.short_src or "unknown source", n.linedefined or "--", name) + end + else + return "unknown" + end +end +function debugger.showstats(printer,threshold) + printer = printer or texio.write or print + threshold = threshold or 0 + local total, grandtotal, functions = 0, 0, 0 + printer("\n") -- ugly but ok + -- table.sort(counters) + for func, count in pairs(counters) do + if count > threshold then + local name = getname(func) + if not name:find("for generator") then + printer(format("%8i %s", count, name)) + total = total + count + end + end + grandtotal = grandtotal + count + functions = functions + 1 + end + printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +end + +-- two + +--~ local function hook() +--~ local n = getinfo(2) +--~ if n.what=="C" and not n.name then +--~ local f = tostring(debug.traceback()) +--~ local cf = counters[f] +--~ if cf == nil then +--~ counters[f] = 1 +--~ names[f] = n +--~ else +--~ counters[f] = cf + 1 +--~ end +--~ end +--~ end +--~ function debugger.showstats(printer,threshold) +--~ printer = printer or texio.write or print +--~ threshold = threshold or 0 +--~ local total, grandtotal, functions = 0, 0, 0 +--~ printer("\n") -- ugly but ok +--~ -- table.sort(counters) +--~ for func, count in pairs(counters) do +--~ if count > threshold then +--~ printer(format("%8i %s", count, func)) +--~ total = total + count +--~ end +--~ grandtotal = grandtotal + count +--~ functions = functions + 1 +--~ end +--~ printer(format("functions: %s, total: %s, grand total: %s, threshold: %s\n", functions, total, grandtotal, threshold)) +--~ end + +-- rest + +function debugger.savestats(filename,threshold) + local f = io.open(filename,'w') + if f then + debugger.showstats(function(str) f:write(str) end,threshold) + f:close() + end +end + +function debugger.enable() + debug.sethook(hook,"c") +end + +function debugger.disable() + debug.sethook() +--~ counters[debug.getinfo(2,"f").func] = nil +end + +function debugger.tracing() + local n = tonumber(os.env['MTX.TRACE.CALLS']) or tonumber(os.env['MTX_TRACE_CALLS']) or 0 + if n > 0 then + function debugger.tracing() return true end ; return true + else + function debugger.tracing() return false end ; return false + end +end + +--~ debugger.enable() + +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) +--~ print(math.sin(1*.5)) + +--~ debugger.disable() + +--~ print("") +--~ debugger.showstats() +--~ 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.mkii b/tex/context/base/type-ini.mkii new file mode 100644 index 000000000..fa7b7934f --- /dev/null +++ b/tex/context/base/type-ini.mkii @@ -0,0 +1,743 @@ +%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 tmf] +\usetypescriptfile[\f!typeprefix siz] + +\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 +\fi + +\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 {\chardef\typescriptmethod\plusone\dotripleempty\dousetypescript} +\unexpanded\def\usetypescriptexact{\chardef\typescriptmethod\plustwo\dotripleempty\dousetypescript} + +\def\dousetypescript[#1][#2][#3]% + {\expanded{\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 \chardef\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} + +\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 + \long\def\starttypescript##1\stoptypescript + {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescript##1\stoptypescript}}% + \long\def\starttypescriptcollection##1\stoptypescriptcollection + {\global\loadedtypescripts\@EA{\the\loadedtypescripts\starttypescriptcollection##1\stoptypescriptcollection}}% + \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}% + \expanded{\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\else\donefalse\fi + \else\ifx#1\typescript@@all + \donetrue + \else\ifx\@@typescriptcheck\typescript@@all + \donetrue + \else\expanded{\doifcommonelse{\@@typescriptcheck}{#1}}\donetrue\donefalse\ifdone + \let#2\commalistelement + \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]{\expanded{\processcommalist[#1]}\dopreloadmapfile} +\def\loadmapfile [#1]{\expanded{\processcommalist[#1]}\loadthemapfile} +\def\unloadmapfile [#1]{\expanded{\processcommalist[#1]}\unloadthemapfile} + +% too soon, no driver known, \ifproductionrun \loadallfontmapfiles \fi + +% temp hack, will become just \addto + +\ifx\pdftexversion\undefined + + \def\loadthemapfile#1% + {\splitfiletype{#1}% + \doglobal\addtocommalist\splitoffname\allfontmapsfiles} + +\else\ifnum\pdftexversion<120 % no overloading + + \def\loadthemapfile#1% + {\splitfiletype{#1}% + \doglobal\pretocommalist\splitoffname\allfontmapsfiles} + +\else + + \def\loadthemapfile#1% + {\splitfiletype{#1}% + \doglobal\addtocommalist\splitoffname\allfontmapsfiles} + +\fi \fi + +\def\unloadthemapfile#1% + {\splitfiletype{#1}% + \doglobal\removefromcommalist\splitoffname\allfontmapsfiles} + +\let\usedmapfile\gobbletwoarguments +\let\usedmapline\gobbletwoarguments + +\def\doregisterloadedmapfile#1% + {\immediatewriteutilitycommand{\usedmapfile{=}{#1}}} + +\def\doloadfontmapfile#1% + {\ifundefined{#1\c!state}% + \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% + {\ifundefined{#1\c!state}% + \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 + \expanded{\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][#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 + +% old and obsolete +% +% \def\doreadfontdefinitionfile#1#2% #1 = set/switch state +% {\ifundefined{\??tf#2\c!default}% +% \pushmacro\fontclass +% \setcurrentfontclass\empty +% \pushmacro\@@typescriptone \edef\@@typescriptone {\truetypescript{#2}}% +% \pushmacro\@@typescripttwo \let\@@typescripttwo \empty +% \pushmacro\@@typescriptthree\let\@@typescriptthree\empty +% \typescriptfoundfalse +% \dododousetypescript{\f!typeprefix pre}% +% \popmacro\@@typescriptthree +% \popmacro\@@typescripttwo +% \popmacro\@@typescriptone +% \iftypescriptfound \else +% \normaldoreadfontdefinitionfile{#1}{#2}% +% \fi +% \setcurrentfontclass\empty +% \popmacro\fontclass +% \else\ifcase#1\relax +% \switchtotypeface[#2]% +% \else +% \setuptypeface[#2]% +% \fi\fi} +% +% new and obeying fontclasses (but still obsolete) + +\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} + +% \usetypescript [berry] [ec] + +\protect \endinput 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-ini.tex b/tex/context/base/type-ini.tex deleted file mode 100644 index 17b1c2088..000000000 --- a/tex/context/base/type-ini.tex +++ /dev/null @@ -1,721 +0,0 @@ -%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 (ini)} - -%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 -% -% \beginXETEX \font -% \usetypescriptfile[\f!typeprefix xtx] % xetex definitions -% \endXETEX - -\usetypescriptfile[\f!typeprefix tmf] -\usetypescriptfile[\f!typeprefix siz] - -\beginOLDTEX \font - \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 - -\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 {\chardef\typescriptmethod\plusone\dotripleempty\dousetypescript} -\unexpanded\def\usetypescriptexact{\chardef\typescriptmethod\plustwo\dotripleempty\dousetypescript} - -\def\dousetypescript[#1][#2][#3]% - {\expanded{\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 \chardef\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} - -\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 - \long\def\starttypescript##1\stoptypescript - {\global\loadedtypescripts\@EA{\the\loadedtypescripts - \starttypescript##1\stoptypescript}}% - \long\def\starttypescriptcollection##1\stoptypescriptcollection - {\global\loadedtypescripts\@EA{\the\loadedtypescripts - \starttypescriptcollection##1\stoptypescriptcollection}}% - \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}% - \expanded{\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 - \doifnextcharelse[\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 - {\doifnextcharelse[\dostarttypescripttwo\dostarttypescriptyes} - -\long\def\redostarttypescripttwo - {\doifnextcharelse[\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\else\donefalse\fi - \else\ifx#1\typescript@@all - \donetrue - \else\ifx\@@typescriptcheck\typescript@@all - \donetrue - \else\expanded{\doifcommonelse{\@@typescriptcheck}{#1}}\donetrue\donefalse\ifdone - \let#2\commalistelement - \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]{\expanded{\processcommalist[#1]}\dopreloadmapfile} -\def\loadmapfile [#1]{\expanded{\processcommalist[#1]}\loadthemapfile} -\def\unloadmapfile [#1]{\expanded{\processcommalist[#1]}\unloadthemapfile} - -% too soon, no driver known, \ifproductionrun \loadallfontmapfiles \fi - -% temp hack, will become just \addto - -\ifx\pdftexversion\undefined - - \def\loadthemapfile#1% - {\splitfiletype{#1}% - \doglobal\addtocommalist\splitoffname\allfontmapsfiles} - -\else\ifnum\pdftexversion<120 % no overloading - - \def\loadthemapfile#1% - {\splitfiletype{#1}% - \doglobal\pretocommalist\splitoffname\allfontmapsfiles} - -\else - - \def\loadthemapfile#1% - {\splitfiletype{#1}% - \doglobal\addtocommalist\splitoffname\allfontmapsfiles} - -\fi \fi - -\def\unloadthemapfile#1% - {\splitfiletype{#1}% - \doglobal\removefromcommalist\splitoffname\allfontmapsfiles} - -\let\usedmapfile\gobbletwoarguments -\let\usedmapline\gobbletwoarguments - -\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}% - \doregisterloadedmapfile{#1}% - \doloadmapfile{=}{#1.\f!fontmapextension}% +/add =/replace -/remove - \setxvalue{#1\c!state}{1}% - \fi} - -\def\doreportfontmapfile#1% - {\ifundefined{#1\c!state}% - \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]% - {\setvalue{\??ts::#1}{#2}} - -% 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 - \expanded{\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][#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} - -% 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]}}}} - -\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 - -% old and obsolete -% -% \def\doreadfontdefinitionfile#1#2% #1 = set/switch state -% {\ifundefined{\??tf#2\c!default}% -% \pushmacro\fontclass -% \setcurrentfontclass\empty -% \pushmacro\@@typescriptone \edef\@@typescriptone {\truetypescript{#2}}% -% \pushmacro\@@typescripttwo \let\@@typescripttwo \empty -% \pushmacro\@@typescriptthree\let\@@typescriptthree\empty -% \typescriptfoundfalse -% \dododousetypescript{\f!typeprefix pre}% -% \popmacro\@@typescriptthree -% \popmacro\@@typescripttwo -% \popmacro\@@typescriptone -% \iftypescriptfound \else -% \normaldoreadfontdefinitionfile{#1}{#2}% -% \fi -% \setcurrentfontclass\empty -% \popmacro\fontclass -% \else\ifcase#1\relax -% \switchtotypeface[#2]% -% \else -% \setuptypeface[#2]% -% \fi\fi} -% -% new and obeying fontclasses (but still obsolete) - -\def\doreadfontdefinitionfile#1#2% #1 = set/switch state - {\ifundefined{\??tf#2\c!default}% - \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 - \else\ifcase#1\relax - \switchtotypeface[#2]% - \else - \setuptypeface[#2]% - \fi\fi} - -\fetchruntimecommand \typetypescript {\f!typeprefix\s!run} - -% \usetypescript [berry] [ec] - -\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(">")/">" + P("<")/"<") * space local compareop = P("<") + P("=") + P(">") + P(">=") + P("<=") + P(">") + P("<") 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(">")/">" + P("<")/"<") * 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ - + - + @@ -463,7 +463,7 @@ - + @@ -4096,7 +4096,7 @@ - + @@ -5647,6 +5647,10 @@ + + + + @@ -7083,6 +7087,8 @@ + + @@ -9986,7 +9992,7 @@ - + @@ -9997,7 +10003,7 @@ - + @@ -10014,7 +10020,7 @@ - + @@ -10056,7 +10062,7 @@ - + @@ -10098,7 +10104,7 @@ - + @@ -10138,7 +10144,7 @@ - + @@ -10152,7 +10158,7 @@ - + @@ -10180,7 +10186,7 @@ - + @@ -10199,7 +10205,7 @@ - + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + @@ -240,6 +241,7 @@ + @@ -298,6 +300,7 @@ + @@ -362,6 +365,7 @@ + @@ -431,6 +435,14 @@ + + + + + + + + @@ -526,6 +538,8 @@ + + @@ -553,6 +567,7 @@ + @@ -599,6 +614,7 @@ + @@ -632,6 +648,7 @@ + @@ -720,9 +737,17 @@ + + + + + + + + @@ -742,8 +767,22 @@ + + + + + + + + + + + + + + @@ -753,6 +792,13 @@ + + + + + + + @@ -763,6 +809,7 @@ + @@ -794,11 +841,18 @@ + + + + + + + @@ -901,6 +955,8 @@ + + @@ -1289,6 +1345,7 @@ + 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 @@ + + + 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 +% Copyright (C) 2007, 2008 Werner Lemberg % % 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 +% Copyright (C) 2008 Werner Lemberg % % 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 , +% +% 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-- +

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).

+ +

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.

+ +

Examples of usage can be found in the font related code.

+--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-- +

Most of the code that had accumulated here is now separated in +modules.

+--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-- +

We start with a registration system for atributes so that we can use the +symbolic names later on.

+--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-- +

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 .

+--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-- +

Access to nodes is what gives its power. Here we +implement a few helper functions. These functions are rather optimized.

+--ldx]]-- + +--[[ldx-- +

When manipulating node lists in , 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 was feasible from the perspective of performance.

+ +

First of all, we noticed that the bottleneck is more with excessive +callbacks (some gets called very often) and the conversion from and to +'s datastructures. However, at the end, we +found that inserting and deleting nodes in a table could become a +bottleneck.

+ +

This resulted in two special situations in passing nodes back to +: a table entry with value false is ignored, +and when instead of a table true is returned, the +original table is used.

+ +

Insertion is handled (at least in 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 inline 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 engine, but this is a not so natural extension.

+ +

When we collapse (something that we only do when really needed), we +also ignore the empty nodes. [This is obsolete!]

+--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-- +

The next function is not that much needed but in we use +for debugging node management.

+--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-- +

Not much is happening here.

+--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-- +

Here we only implement a few helper functions.

+--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-- +

The next function encapsulates the standard loader as +supplied by .

+--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-- +

We need to normalize the scale factor (in scaled points). This has to +do with the fact that uses a negative multiple of 1000 as +a signal for a font scaled based on the design size.

+--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-- +

Before a font is passed to we scale it. Here we also need +to scale virtual characters.

+--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-- +

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.)

+--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-- +

The reason why the scaler is split, is that for a while we experimented +with a helper function. However, in practice the calls are too slow to +make this profitable and the based variant was just faster. A days +wasted day but an experience richer.

+--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-- +

Analyzers run per script and/or language and are needed in order to +process features right.

+--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-- +

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.

+ + +we loop over all lookups +for each lookup we do a run over the list of glyphs +but we only process them for features that are enabled +if we're dealing with a contextual lookup, we loop over all contexts +in that loop we quit at a match and then process the list of sublookups +we always continue after the match + + +

In we do this for each font that is used in a list, so in +practice we have quite some nested loops.

+ +

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).

+ +

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.

+--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-- +

We start with a lot of tables and related functions.

+--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-- +

Here we go.

+--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-- +

This module is a bit more split up that I'd like but since we also want to test +with plain it has to be so. This module is part of +and discussion about improvements and functionality mostly happens on the + mailing list.

+ +

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.

+ +

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.

+ +

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 users ask for it.

+ +

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.

+ +

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 + 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 has to include +then in the output eventually.

+ +

The raw table as it coms from gets reorganized in to fit out needs. +In 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).

+ +

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.

+ +

As with the code, we may decide to store more information in the + table.

+ +

Incrementing the version number will force a re-cache. We jump the number by one +when there's a fix in the library or code that +results in different tables.

+--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 "" + 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-- +

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.

+--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-- +

I will implement multiple chain replacements once I run into a font that uses +it. It's not that complex to handle.

+--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-- +

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:

+ + +xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx + + +

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.

+--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-- +

Here we replace start by a single variant, First we delete the rest of the +match.

+--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-- +

Here we replace start by a sequence of new glyphs. First we delete the rest of +the match.

+--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-- +

Here we replace start by new glyph. First we delete the rest of the match.

+--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-- +

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).

+--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-- +

Here we deal with defining fonts. We do so by intercepting the +default loader that only handles .

+--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-- +

We hardly gain anything when we cache the final (pre scaled) + table. But it can be handy for debugging.

+--ldx]]-- + +fonts.version = 1.05 +fonts.cache = containers.define("fonts", "def", fonts.version, false) + +--[[ldx-- +

We can prefix a font specification by name: or +file:. The first case will result in a lookup in the +synonym table.

+ + +[ name: | file: ] identifier [ separator [ specification ] ] + + +

The following function split the font specification into components +and prepares a table that will move along as we proceed.

+--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-- +

A unique hash value is generated by:

+--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-- +

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 .

+--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-- +

We can resolve the filename using the next function:

+--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-- +

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.

+ +

We need to cache when possible. We do cache raw tfm data (from , or ). After that we can cache based +on specificstion (name) and size, that is, only needs a number +for an already loaded fonts. However, it may make sense to cache fonts +before they're scaled as well (store '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.

+ +

Watch out, here we do load a font, but we don't prepare the +specification yet.

+--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-- +

For virtual fonts we need a slightly different approach:

+--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-- +

Next follow the readers. This code was written while +evolved. Each one has its own way of dealing with its format.

+--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-- +

We need to check for default features. For this we provide +a helper function.

+--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-- +

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).

+ +In the previously defined reader (the one resulting in a +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.

+--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-- +

We overload both the and readers.

+--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-- +

Choosing a font by name and specififying its size is only part of the +game. In order to prevent complex commands, 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.

+ +

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.

+ +

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.

+--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(" ",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(" ", 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-- +

This module is a stripped down version of libraries that are used +by . 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 supp-mpl.tex.

+--ldx]]-- + +if metapost and metapost.version then + + --[[ldx-- +

Let's silently quit and make sure that no one loads it + manually in .

+ --ldx]]-- + +else + + local format, concat, abs = string.format, table.concat, math.abs + + local mplib = require ('mplib') + local kpse = require ('kpse') + + --[[ldx-- +

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.

+ +

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 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 + metapost.make(name,mem_name) that does the job.

+ --ldx]]-- + + metapost = metapost or { } + metapost.version = 1.00 + metapost.showlog = metapost.showlog or false + metapost.lastlog = "" + + --[[ldx-- +

A few helpers, taken from l-file.lua.

+ --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-- +

We use the library unless a finder is already + defined.

+ --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-- +

You can use your own reported if needed, as long as it handles multiple + arguments and formatted strings.

+ --ldx]]-- + + metapost.report = metapost.report or function(...) + texio.write(format("",format(...))) + end + + --[[ldx-- +

The rest of this module is not documented. More info can be found in the + manual, articles in user group journals and the files that + ship with .

+ --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-- +

We removed some message and tracing code. We might even remove the flusher

+ --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-- +

Support for specials has been removed.

+ --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. -- cgit v1.2.3